解放与信号处理(SIGCHLD专门)

时间:2012-05-03 15:10:15

标签: c libevent

这有点是我发现的相关问题的后续内容 here

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

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

This documentation似乎警告在信号事件回调中调度计时器。这似乎不正确(因为我们将在信号处理程序上下文之外)。除了上述警告,我无法通过signalfd()看到这样做的好处。

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

谢谢!

1 个答案:

答案 0 :(得分:2)

来自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信号中的“异步信号安全功能”。使用signalfd方法,这些限制大大减少了。

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

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

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