[英]`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
来填充子进程的退出代码,在这种情况下,始终将errno
为EAGAIN
。
但是,从我的角度来看,如果与此同时无事可做,那么最好不要使用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.