【发布时间】:2019-10-13 23:04:03
【问题描述】:
对 signalfd 的 read() 调用会消耗 SIGCHLD 吗? 或者我需要在之后使用 waitid() 调用吗?
我通过调用 epoll_wait() 在 signalfd 上接收到可读事件,然后我在 signalfd 上执行 read(),它提供了 signalfd_siginfo 中所需的所有信息。
我在 read() 上循环,直到返回 -1 和 errno=EAGAIN。
但是使用 shell 命令 ps aux,进程仍然在这里,<defunct>。
如果我使用 waitid() 循环,我没有问题。 为什么我需要在 read(signalfd) 之后调用 waitid() ?
我在手册页中看不到这种行为,也找不到相关的源示例。
【问题讨论】:
-
与您的代码的散文描述相比,实际代码的minimal reproducible example 将更有效地传达您的情况。
-
我不确定这一点,但我认为
signalfd旨在替换sigaction,而不是替换wait。您总是必须在 SIGCHLD 处理程序中调用wait,所以同样您必须在从 signalfd 收到 SIGCHLD 通知后调用wait。 -
waitid不会“使用 SIGCHILD”,它只是检索终止子的状态。 -
@WilliamPursell,你的意思是 read() 而不是 waitid()?为什么不使用 timerfd 上的 read()
-
@DavidBonnin 我不确定我是否理解您的评论。如果你
readsignalfd创建的文件描述符,我想你可以说你已经“消费了 SIGCHILD”。但是waitid不会那样做。waitid将在您从文件描述符中读取 signalfd_siginfo 结构以检索终止子节点的状态后使用。如果您不检索该状态,则孩子将成为僵尸,并且该状态将保留在ps的输出中,直到它被收割为止。