我正在执行下面的代码,对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");
}
}
}
}发布于 2019-04-23 05:01:59
嗯,您误解了wait系统调用的工作原理。
与malloc/free一样,您只能在每个fork()编辑的进程中成功一次.因此,如果要等待子程序的退出代码,则不必使用while循环,只需调用一次。在您的情况下,等待只会返回-1,原因有两个:
fork()没有成功,所以您正在等待无效的pid。实际上,您应该为wait()调用pid == -1,这是无效的。如果您wait()并且没有进程等待(如果pid变量有一个正数,但是对于一个已经wait()的子进程,您也得到了-1),那么您将从系统调用的wait()系列中得到一个错误。UN*X系统中僵尸进程的任务就是确保已经完成的子进程的wait()仍然有效,并且调用进程获得exit()上子进程所指示的退出代码。WNOHANG参数所做的事情,那么子进程可能仍然在运行(这就是您的情况),并且还没有执行exit() syscall。只有当子进程已经完成时,您才需要退出代码。如果是这样的话,那你最好写:
WNOHANG) do_whatever_you_want_because_you_decided_not_to_wait();( == -1 & errno == EAGAIN)
wait系统调用无法告诉您,&status变量没有被子进程的退出代码填充,只能发送错误信号,在这种情况下,它总是将errno设置为EAGAIN。
但是,从我的观点来看,如果您同时没有什么可做的,那么最好不要使用WNOHANG。这将节省cpu周期和大量的热能投到环境中。发布于 2019-04-21 17:40:53
这里
while(waitpid(pid,&status,WNOHANG)==-1) { }如果没有更多的子进程存在,那么waitpid将返回-1,并使while(true)始终保持不变,从而导致无限循环。
来自waitpid()的手册页。
waitpid():成功后,返回状态已更改的子进程ID;如果指定了WNOHANG,并且存在由pid指定的一个或多个子进程(Ren),但尚未更改状态,则返回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 */
}https://stackoverflow.com/questions/55785052
复制相似问题