繁体   English   中英

`waitpid()'总是返回-1

[英]`waitpid()' always returns -1

我正在执行以下代码,对waitpid()的调用始终返回-1 ,因此下面的代码以无限循环结尾。 如果我将WNOHANG替换为0则该呼叫有效。

void execute(cmdLine* pCmdLine) {
    int status = 0;
    pid_t pid = fork();
    if(pid == 0) {
         if(execvp(pCmdLine->arguments[0], pCmdLine->arguments) == -1) {
             if(strcmp(pCmdLine->arguments[0], "cd") != 0) {
               perror("execute failed\n");
             }
        _exit(1);
        }
    } else {
        if(pCmdLine->blocking == 1) {
            waitpid(pid, &status, 0);
        }
            while(waitpid(pid, &status, WNOHANG) == -1) {
             printf("still -1\n");
            }
         }     
    }
}

好吧,您误解了wait系统调用的工作方式。

malloc/free ,每个fork()进程只能成功等待一次waitpid() ,因此,如果您要等待子代的退出代码,则while循环永远不需要,您必须调用它只有一次。 在您的情况下,等待只会返回-1 ,这有两个原因:

  • fork()没有成功,因此您正在等待无效的pid 确实,您应该为pid == -1调用wait() ,这是无效的。 如果您使用wait()并且没有等待的过程(如果pid变量的值为正数,但是已经使用过wait()子过程,您也会得到-1 ),那么您会从任何wait()系列系统调用。 UN * X系统中的僵尸进程的任务就是这样,以确保对已完成的子进程的wait()仍然有效,并且调用进程获取该子进程在exit()上发出的退出代码。
  • 您明确地说您不会等待该过程完成。 应该清楚的是,如果您不打算等待进程终止,那么这就是使用WNOHANG参数执行的操作,那么子进程可能仍在运行(这是您的情况)并且尚未完成exit() syscall。 如果子进程已经完成,则只需要退出代码。 如果是这种情况,那么您最好编写:

     while(waitpid(pid, &status, WNOHANG) == -1 && errno == EAGAIN) do_whatever_you_want_because_you_decided_not_to_wait(); 

    wait系统调用没有办法告诉您&status变量还没errno通知errno来填充子进程的退出代码,在这种情况下,始终将errnoEAGAIN

    但是,从我的角度来看,如果与此同时无事可做,那么最好不要使用WNOHANG 这样可以节省CPU周期并节省大量散发到环境中的热能。

这里

 while(waitpid(pid,&status,WNOHANG)==-1) { }

如果不再存在子进程,则waitpid返回-1 ,它始终使while(true)并导致无限循环。

waitpid()的手册页开始。

waitpid():成功时,返回状态已更改的子进程的ID 如果指定了WNOHANG ,并且存在由pid指定的一个或多个孩子,但尚未更改状态,则返回0 出错时,返回-1

这意味着,当没有其他孩子等待时,它返回-1 所以要么让它像

if() { /* child process. can be multiple */
} 
else { /* parent process */
    while(waitpid(pid,&status,WNOHANG) != -1) { /* when there is no more child process exists then it terminate */ 
    }
}

要么

if() { /* child process. can be multiple */
} 
else { /* parent process */
  while(waitpid(pid,&status,WNOHANG) == -1);  /* dummy while ..when there is no more child process exists then it terminate */ 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM