使用waitpid在后台运行进程?

10
我正在尝试模仿bash特性,如果在命令的末尾找到"&",则在后台运行进程。 我有以下功能...我不认为它正在做我想要做的事情
int execute(char* args[],int background,int *cstatus){
    pid_t   child;
    pid_t   ch;                         /*Pid of child returned by wait*/
    if ((child = fork()) == 0){                 /*Child Process*/
        execvp(args[0],args);       
        fprintf(stderr, "RSI: %s: command not found\n",args[0]); /*If execvp failes*/
        exit(1);

    }else{          /*Parent process*/
        if (child== (pid_t)(-1)) {
            fprintf(stderr,"Fork failed\n"); exit(1);
        }else{
            if (background==0){             /*If not running in background..wait for process to finish*/
                ch = wait(cstatus);
            }else{
                printf("%ld Started\n",(long)getpid());
        /*  printf("Parent: Child %ld exited with status = %ld\n", (long) ch, (long)cstatus);
    */  }}
    }
return 0;
}
int wait_and_poll(int *cstatus){
    pid_t status;
    status = waitpid(-1,cstatus,WNOHANG);
    if (status>0){
        fprintf(stdout,"%ld Terminated.\n",(long) status);
    }
return 0;
}
如果我只运行"ls -l",它会按预期工作。但如果我想在后台运行"ls"并使程序继续接受新命令,我将设置background标志并调用该函数。我希望它在后台运行进程,并告诉我它已经创建了该进程,然后提示我接受下一个命令。
2个回答

7
我认为waitpid(-1, &cstatus, WNOHANG);并不是你想要的功能。你需要检查它的返回值。如果返回值> 0,那么就是已经退出的子进程的PID。如果返回值是0-1,则没有子进程改变状态。
在每个命令运行之前和/或之后,您可以调用waitpid(-1, &cstatus, WNOHANG);。在循环中调用它以捕获多个子进程退出。
您还可以处理SIGCHILD信号。您的进程将立即收到此信号,此时子进程已退出,这很好,如果您想立即报告子进程终止,而不必等待用户输入。

如果我有多个后台进程在运行,我需要存储它们的pid并使用waitpid循环遍历吗? - user1411893
绝对不是。调用waitpid(-1, &cstatus, WNOHANG)。这将提供您所需的所有信息。 - n. m.
1
我更新了代码,现在在执行方法之前和之后调用wait_and_poll方法。但是状态始终为-1或0,即使在我关闭后台程序或使用Kill命令后也是如此。 - user1411893
我不确定为什么会发生这种情况。如果waitpid返回-1,errno的值是多少?你确定没有其他地方调用了"wait"和其他相关函数吗? - n. m.
我有一个小的示例程序,它与waitpid完全正常工作,请参见pastebin - n. m.

3

这很简单。 假设你有一个进程P,其id为pid。

如果你想让它在后台运行(可以通过在输入字符串的末尾添加&来识别),你应该这样做

//some code
id=fork();
if(id==0)
{
//child does work here
}
else
{
//Parent does work here
if(!strcmp(last string,"&")==0)waitpid(id,&status,0);
}

因此,如果您请求后台执行,则父级不会等待,否则它会等待。

1
但是,此解决方案不支持“jobs”功能。 - alhelal
但这会创建僵尸子进程,可能会成为一个问题。 - Mysterious Jack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接