【问题标题】:waitpid returns pid=0 and WIFEXITED=1 how to get pid?waitpid 返回 pid=0 和 WIFEXITED=1 如何获取 pid?
【发布时间】:2014-02-24 09:41:39
【问题描述】:

步骤:

在不同的程序组中分叉并启动进程
使用 SIGTSTP 停止进程
使用 SIGCONT 重启进程
进程结束

问题: SIGCHLD 处理程序有:

waitpid(-1, &status, WNOHANG | WUNTRACED);

返回 pid=0 和 WIFEXITED=1 所以,进程退出了,但我无法获得pid? 我需要pid。

从手册页:“如果指定了 WNOHANG 并且 pid 指定的一个或多个子项存在,但尚未更改状态,则返回 0”
但似乎状态已更改为退出。

【问题讨论】:

    标签: c linux pid waitpid


    【解决方案1】:

    如果返回的 pid 为 0,则状态毫无意义。考虑一下。返回 0 表示您有一个或多个孩子尚未更改状态。尚未改变状态的孩子的状态会是什么?如果有多个孩子,状态码引用哪个孩子?

    这类似于在成功调用时检查 errno。之前调用中的任何内容都可以在 errno 中,但它与最近一次成功的调用无​​关,因为 errno 通常不会设置为成功。

    【讨论】:

    • +1 status 仅在返回值 > 0 时才被修改
    • 所以,这帮助我在别处寻找错误。谢谢。
    • 另外请记住,如果使用 WUNTRACED,waitpid()(当然还有 wait())如果有一个进程已被停止(通过 SIGSTOP)将返回。 尽管手册页上写着“WUNTRACED 由 pid 指定的任何已停止子进程的状态,以及自停止后尚未报告其状态的任何子进程的状态,也应报告给请求进程。”,我测试的 2.6.32 内核将不会改变状态变量。您唯一的指示(据我所知)等待返回是 SIGSTOP 的结果,返回值为 -1。
    【解决方案2】:

    waitpid的返回值是被等待的孩子的PID。

    【讨论】:

    • pid 不为零...
      来自手册页:“如果指定了 WNOHANG 并且 pid 指定的一个或多个子项存在,但尚未更改状态,则返回 0"
      但状态似乎已更改为已退出。
    • @donkon:啊,好的:父母可能会在孩子收割之前收到信号。在这种情况下,您可能不应该在信号处理程序中使用 WNOHANG。
    • @KerrekSB:在SIGCHLD 的信号处理程序中通常有一个带有waitpid(-1, &status, WNOHANG) 的循环(例如,在不破坏waitpid 功能的情况下模拟SA_NOCLDWAIT)。另外,如果SIGCHLD 没有表明状态是立即可用的,那么它的意义何在?
    • @jilles:您不必在信号处理程序中运行waitpid。如果你在其他多路复用循环中运行它,你可能需要一个非阻塞版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 2023-04-02
    • 2014-05-16
    • 1970-01-01
    相关资源
    最近更新 更多