如果我将信号处理程序(用于SIGCHLD
设置为sigaction
而不使用SA_NODEFER
,并且进程在处理程序内部再次接收到相同的信号,则第二个信号会丢失还是会它在处理程序返回时交付?
答案 0 :(得分:2)
从历史上看,信号可能会丢失。最初,这只是一个缺少的编程接口,因为sigaction
和sigprocmask
不存在,因此为了暂时停止信号的传递,您必须将signal
函数与{{ 1}},当然,在SIG_IGN
处于活动状态期间,如果在此时间内到达,则任何信号都会消失。
使用SIG_IGN
(以及在sigprocmask
中安装的信号处理程序的明确语义),信号可能会变为暂挂状态,内核会在其中记录信号可用的事实,而无需实际发送。信号一旦被解除阻塞(或明确解除阻塞),便会被消耗。
但是,待处理信号不仅是简单的计数器(针对每个信号),而且还包含其他信息,例如,如果使用sigqueue
生成了信号,则发送PID和信号值。这意味着,如果要排队任意数量的信号,内核实际上必须分配内存。 Linux仅对实时信号执行此操作。每个用户的可排队信号数量限制为sigaction
:
RLIMIT_SIGPENDING
有关详细信息,请参见signal(7)
。
非实时信号不会以这种方式排队。一个过程将仅观察到第一个待处理的信号。从某种意义上说,随后的信号可能看起来像丢失了,但是至少传递了一个信号 ,因此这与原始的$ ulimit -a | grep sign
pending signals (-i) 47913
竞争条件不同。
对于诸如SIG_IGN
和SIGCHLD
之类的某些非实时信号,可能看起来好像它们在排队一样,但这是因为它们是为特定事件而生成的(与某些现有事件捆绑在一起)内核资源(例如进程),并且在阻止信号的同时可能发生多个此类事件。
另请参阅this earlier answer。