这有点是我发现的相关问题的后续内容 here。
在链接的问题中,提到使用signalfd()
并将该fd与libevent一起使用。在那个问题中,OP没有列出他使用signalfd()
而不是使用信号处理设施的原因。
在这两种方法中,您将在信号处理程序之外处理回调。
This documentation似乎警告在信号事件回调中调度计时器。这似乎不正确(因为我们将在信号处理程序上下文之外)。除了上述警告,我无法通过signalfd()
看到这样做的好处。
关于两种方法之间的差异或关于警告的任何输入
谢谢!
答案 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,因为这两种方法都会崩溃多次出现的信号。