指定特定信号处理程序的经典方法是通过sigaction
。 Linux还提供了signalfd
功能,我们可以在其中将信号连接到文件描述符,然后将select/(e)poll应用于该描述符,这完全符合许多事件循环驱动系统的概念。
我想知道两种机制发生冲突时会发生什么/应该发生什么。可以有比赛条件吗?在signalfd联机帮助页(http://man7.org/linux/man-pages/man2/signalfd.2.html)上,我们阅读:
因此,它说“通常”,我们使用信号掩码是为了防止(默认)处理程序处理信号。并不是说当我们有一个文件描述符连接时,我们必须阻塞信号。不幸的是,手册页没有指定当我们不阻塞信号时会发生什么。
这看起来像行为不明确。我不认为这实际上不是定义明确的,并且想知道这里是否有人知道i)我是否可以找到有关系统应如何运行的详细规范或ii)它如何运行。
我特别感兴趣的是执行顺序:
某个信号的
这是未定义的行为,还是对于必须发生的事情有标准/规范?处理程序是否总是优先于文件描述符?是否调用了处理程序,并且文件描述符触发了一个事件?设置
sigaction
是否会更改信号掩码,从而无需执行步骤(2)?我可以尝试从涉及实际代码的系统测试中得出实际行为。但是,我当然更喜欢查找详细的文档,并认为自己本人找不到正确的引用文献。
最佳答案
signalfd
的行为与sigwaitinfo
相同,只是您可以通过文件描述符访问信息。这意味着signalfd
同步接收信号,并且首先调用信号处理程序(或默认设置)。
来源: TLPI第22.10和22.11章(M. Kerrisk)。
行为是明确定义的,但不一定是人们期望的那样,联机帮助表的措词也很差。说“通常...应该”表明您不是必须这样做,或者更糟糕的是作者不确定。
如果您希望它“正常”运行,即您通常期望的方式(请参见,我也“正常”使用),则必须屏蔽信号。否则,该信号将通过文件描述符提供,但仍将首先调用处理程序(这完全合法,但是大多数人可能会认为这种“怪异行为”)。
因此,存在两种不同的比赛条件。一个条件就是您要询问的条件,但是尽管该行为有点出乎意料,但它是明确定义的(并已记录在案),并且如果您考虑一下,那么它并不是严格意义上的竞争条件。而是一种“双重交付”。
另一个竞争条件是在创建signalfd
之后但在您阻止信号之前信号到达的可能性。这是不太可能的,但原则上可能会发生这种情况。幸运的是,解决方案很简单,您可以先阻止信号,然后创建文件描述符(如果在两者之间到达信号,则文件描述符将立即准备就绪)。
您命名的命令序列(创建文件描述符,取消阻止,然后是sigaction
)具有相似的竞争条件。您应该首先安装处理程序,然后解除阻止,否则在处理程序到达之前可能会发出信号。但这与signalfd
无关。在任何情况下,文件描述符仍然可以用来读取信号,但是如果在解除阻止和安装处理程序之间到达信号,则默认配置可能会终止该过程。
关于linux - signalfd和sigaction之间会存在竞争吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20228092/