【问题标题】:after read(signalfd), does it need a call to waitid()?读取(signalfd)之后,是否需要调用waitid()?
【发布时间】: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 的输出中,直到它被收割为止。

标签: c linux signals


【解决方案1】:

您需要致电wait 从signalfd 获取SIGCHLD。您从ps 输出的<defunct> 清楚地证明了这一点。

如果您从不关心子进程返回码,请将SIGCHLD 设置为由SIG_IGN 处理。没有僵尸了。

【讨论】:

  • 我已经有了 read() 的孩子的返回码。它与使用 waitid() 获得的信息相同。所以 waitid() 仅作为消费子服务,而不是获取信息。通过 read() “有点像 read timerfd” 直接使用可能会更高效、更连贯。
  • @DavidBonnin:可能是什么和现在是两个不同的东西。
猜你喜欢
  • 2013-11-27
  • 1970-01-01
  • 2011-04-09
  • 2014-11-28
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多