c - `waitpid()' 始终返回 -1

标签 c linux unix waitpid

我正在执行下面的代码,并且对 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一样,你只能成功waitpid()每个 fork() 仅一次编辑过程...所以 while如果您要等待子级的退出代码,则永远不需要循环,只需调用它一次。等待将返回 -1在你的情况下,有两个原因:

  • fork()没有成功,所以您正在等待无效的pid 。事实上,您应该调用wait()对于 pid == -1 ,这是无效的。万一你wait()并且没有要等待的进程(如果 pid 变量具有正数,但对于已经 wait() ed 子进程,您还会得到 -1 ),您会从任何 wait() 中收到错误系统调用家族。 UN*X 系统中僵尸进程的使命就是这样,以确保wait()对于已经完成的子进程仍然有效,并且调用进程获取子进程在 exit() 上发出的退出代码信号。 .
  • 您明确表示您不会等待该过程完成。应该清楚的是,如果您不打算等待进程终止,那么这就是您对 WNOHANG 所做的事情。参数,那么子进程仍然可以运行(这是你的情况)并且尚未完成 exit()系统调用。您只需要退出代码以防子进程已经完成。如果是这种情况,那么你最好这样写:

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

    wait系统调用无法告诉您 &status变量尚未填充子进程的退出代码而不是发出错误信号,在这种情况下,它始终设置 errnoEAGAIN

    但是,从我的角度来看,如果你同时没有什么可做的,那么你最好不要使用 WNOHANG 。这将节省 CPU 周期并减少向环境排放的大量热能。

关于c - `waitpid()' 始终返回 -1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55785052/

相关文章:

linux bash 意外输出 echo

regex - 通过 sed 取消注释结束赞誉

linux - awk命令解析grep

unix - 计数没有。 Unix中文件中一行的分隔符

c - 输入 case 时切换 case 菜单不会退出程序

c - 将指针传递给结构中的数组

c - 为什么我们在 C 中传递 Structure 参数时使用双指针?

c - C程序控制台输入的奇怪现象

linux - 从文件名中删除某些字符

unix - 为 db2 客户端中的数据库指定默认模式