【问题标题】:WEXITSTATUS(childStatus) returns 0 but waitpid returns -1WEXITSTATUS(childStatus) 返回 0 但 waitpid 返回 -1
【发布时间】:2014-05-16 22:33:51
【问题描述】:

据我所知,如果 waitpid 返回 -1 则为错误情况。如何从 WEXITSTATUS(childStatus) 中的子进程获得成功 (EXIT_SUCCUSS)?

waitpid 中的 childStatus 和 WEXITSTATUS(childStatus) 的返回值有什么区别?一样吗?

pid_t returnValue = waitpid(Checksum_pid, &childStatus, WNOHANG);
printf("return value = %d", returnValue);
printf("return value = %d", childStatus);

if (WIFEXITED(childStatus))
        {
            printf("Exit Code: _ WEXITSTATUS(childStatus)") ;    
            //Proceed with other calculation.  
        }

【问题讨论】:

    标签: c linux waitpid wexitstatus


    【解决方案1】:

    使用选项WNOHANG 时,我预计大部分时间waitpid 将返回-1errno 设置为@987654325 @。

    无论如何,只要waitpid 确实 返回-1,您不应该查看childStatus,这(据我所知)可能只是垃圾。相反,请查看errno,并妥善处理。

    否则,就目前而言,您的代码似乎没问题,您应该能够从childStatus 中提取0EXIT_SUCCESS

    waitpid 的手册页建议使用以下示例代码:

       if (WIFEXITED(status)) {
           printf("exited, status=%d\n", WEXITSTATUS(status));
       } else if (WIFSIGNALED(status)) {
           printf("killed by signal %d\n", WTERMSIG(status));
       } else if (WIFSTOPPED(status)) {
           printf("stopped by signal %d\n", WSTOPSIG(status));
       } else if (WIFCONTINUED(status)) {
           printf("continued\n");
       }
    

    尽管在此添加最终的 else printf("oops?\n") 语句可能是个好主意。

    【讨论】:

    • 是否可以在定期间隔后执行 waitpid 以使其成功?我总是得到-1...
    • 我按照你的建议尝试了上面提到的。我一直从waitpid获得-1返回值,errorno为ECHILD。但是 WIFEXITED(status) 返回 1 而 WEXITSTATUS(status) 返回 0。你能建议我在这种情况下如何进行吗?
    • @kapilddit:如果将WNOHANG 替换为0 会发生什么?
    • 我尝试使用 0(而不是 WNOHANG),但问题仍然相同。 waitpid 返回 -1 并返回错误 ECHILD。我在 ubuntu 中执行了相同的代码,它给子 pid 作为 waitpid 的返回值,而退出代码为 0。我不知道为什么我用相同的代码得到不同的行为。
    • @kapilddit:进一步的建议:手册页说“如果 SIGCHLD 设置为 SIG_IGN ... 那么 ... 对 waitpid() 的调用 ... 将阻塞直到所有孩子们已经终止,然后失败,errno 设置为 ECHILD"。
    【解决方案2】:

    WIFEXITED 将读取存储在 childStatus 中的任何值,它只是一个整数,因此它不必来自 waitpid() - 试试 eg

    for(i = 0; i < 1234; i++)
            printf("WIFEXITED(%d) %s\n", i, WIFEXITED(i) ? "yes" : "no");
    

    childSTatus 和 WIFEXITED(childStatus) 的区别有点棘手…… 基本上退出状态被滥用来告诉退出状态杀死进程的信号:你想要类似的东西

    struct exitstatus {
            int status;
            int signalnumber;
            enum { exited, signaled };
    };
    

    但是这些信息已经以某种方式被压缩成一个整数(我不确定是否在任何地方定义了确切的细节):例如,在我的计算机上,低 8 位用于信号编号(如果有)和8-15 位用于退出代码。 任何地方的重要一点是,您不需要知道它是如何发生的,只需知道如何通过 WIFEXITED 和朋友获得您想要的结果。

    【讨论】:

    • 什么情况下我会从waitpid得到-1返回值?我将 ECHILD 作为错误/错误代码。在 waitpid 中,我是否需要传递我想知道其状态的 childpid?只有在父进程中我才能请求子进程的状态或在其他进程中我也可以请求特定pid的状态?
    • waitpid 的引用在pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html; waitpid 可以做这两件事,即等待任何进程/特定进程;是的,仅在父进程中(除非您计算重新父进程)
    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多