2

这在某种程度上是我在此处找到的相关问题的后续行动 。

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

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

该文档似乎警告在信号事件回调中调度计时器。这似乎不对(因为我们将在信号处理程序上下文之外)。除了上述警告之外,我看不出使用signalfd().

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

谢谢!

4

1 回答 1

2

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

/* 信号.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,因为这两种方法都会折叠多次出现的信号。

于 2012-05-09T08:12:50.170 回答