被屏蔽的信号会丢失还是排在队列中?

时间:2019-01-15 08:22:21

标签: linux signals posix

如果我将信号处理程序(用于SIGCHLD设置为sigaction而不使用SA_NODEFER,并且进程在处理程序内部再次接收到相同的信号,则第二个信号会丢失还是会它在处理程序返回时交付?

1 个答案:

答案 0 :(得分:2)

从历史上看,信号可能会丢失。最初,这只是一个缺少的编程接口,因为sigactionsigprocmask不存在,因此为了暂时停止信号的传递,您必须将signal函数与{{ 1}},当然,在SIG_IGN处于活动状态期间,如果在此时间内到达,则任何信号都会消失。

使用SIG_IGN(以及在sigprocmask中安装的信号处理程序的明确语义),信号可能会变为暂挂状态,内核会在其中记录信号可用的事实,而无需实际发送。信号一旦被解除阻塞(或明确解除阻塞),便会被消耗。

但是,待处理信号不仅是简单的计数器(针对每个信号),而且还包含其他信息,例如,如果使用sigqueue生成了信号,则发送PID和信号值。这意味着,如果要排队任意数量的信号,内核实际上必须分配内存。 Linux仅对实时信号执行此操作。每个用户的可排队信号数量限制为sigaction

RLIMIT_SIGPENDING

有关详细信息,请参见signal(7)

非实时信号不会以这种方式排队。一个过程将仅观察到第一个待处理的信号。从某种意义上说,随后的信号可能看起来像丢失了,但是至少传递了一个信号 ,因此这与原始的$ ulimit -a | grep sign pending signals (-i) 47913 竞争条件不同。

对于诸如SIG_IGNSIGCHLD之类的某些非实时信号,可能看起来好像它们在排队一样,但这是因为它们是为特定事件而生成的(与某些现有事件捆绑在一起)内核资源(例如进程),并且在阻止信号的同时可能发生多个此类事件。

另请参阅this earlier answer