使用waitpid在后台运行进程?

时间:2013-01-27 14:29:42

标签: c process waitpid

如果“&”我试图模仿后台运行进程的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 ..并让程序继续接受新命令我调用函数,后台标志设置为1和我希望它在后台运行该进程,告诉我它已经创建了进程..然后提示接受下一个命令。

2 个答案:

答案 0 :(得分:5)

我不认为waitpid(-1, &cstatus, WNOHANG);做你认为它做的事。您需要检查其返回值。如果是> 0,那就是退出的子进程的PID。如果它是0-1,则没有子进程更改状态。

您可以在运行每个命令之前和/或之后调用waitpid(-1, &cstatus, WNOHANG);。在循环中调用它以捕获多个子出口。

您也可以处理SIGCHILD。您的流程将在孩子退出后立即收到此信号,如果您想立即报告子流程终止,而不等待用户的输入,这是很好的。

答案 1 :(得分:2)

这很简单。 假设您有一个带有id pid的进程P.

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

//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);
}

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