解放和信号处理(特别是SIGCHLD)

这有点是我在这里找到的相关问题的后续内容。

在链接的问题中,提到使用signalfd()并将该fd与libevent一起使用 。 在那个问题中,OP没有列出为什么他使用signalfd()而不是使用libevent信号处理设施。

在这两种方法中,您将在信号处理程序之外处理回调。

该文档似乎警告在信号事件回调中调度计时器。 这似乎不正确(因为我们将在信号处理程序上下文之外)。 除了上述警告,我无法看到使用signalfd()执行此操作的好处。

关于两种方法之间的差异或关于警告的任何输入

谢谢!

来自libevent的源代码(v2.0.19-stable)

/ * signal.c

这是我们用于后端的信号处理实现,后端没有更好的方法来进行信号处理。 它使用sigaction()或signal()来设置信号处理程序,并使用套接字对来告诉事件库何时

请注意,我说“事件库”:一次只能设置一个事件库来使用它。 由于历史原因和向后兼容性,如果向event_base A添加信号事件,则向event_base B添加信号事件(任何信号!),event_base B将获得有关信号的通知,但event_base A不会。

在Libevent的某个未来版本中改变这种行为是很好的。 kqueue已经做了一些更明智的事情。 我们可以使用signalfd使Linux上的所有后端做一个合理的事情。 * /

所以现在libevent使用sigaction()如果它可用,并且失败了,signal()。

如果使用signalfd(),通常使用sigprocmask阻塞信号,这样信号就不会导致默认处理程序执行。 然后,您可以使用libevent监视返回的文件句柄并安全地处理来自正常同步代码的信号,而不必担心内存安全或阻塞或中断其他系统调用。

在经典异步信号处理程序(即使用sigaction注册的那些)中可以安全地执行的操作存在限制。 请参阅man信号中的“异步信号安全function”。 使用signalfd方法,这些限制大大减少了。

关于注册计时器回调的警告可能会引起关注,因为libevent支持这么多平台,并且至少有一个人报告了问题。 请注意,如果您选择/轮询signalfd注册的文件句柄,则无论如何您都不必担心此限制。

编辑:我重新阅读你的问题,并意识到我没有真正回答它。 注册signalfd然后在libevent中使用它的好处是因为它以牺牲可移植性为代价更快。 有计划(http://archives.seul.org/libevent/users/Mar-2010/msg00046.html)将signalfd纳入libevent,但AFAIK还没有发生。

此外,一旦您收到SIGCHLD的通知,您应始终在循环中调用waitpid,直到您获得ENOCHLD,因为这两种方法都会崩溃多次出现的信号。