【发布时间】:2011-07-14 05:06:59
【问题描述】:
我在 Linux 下有一个简单的程序,它在一个循环中向其子进程发送 SIGUSR1 信号。但是当我发送例如有时会发生 10 个信号,表明孩子只收到了其中的 3 个。最后发送的信号始终是 SIGUSR2,并且每次都会收到。
信号是否在排队,或者当进程没有处理前一个信号时,它只是被覆盖了?有没有办法可以在队列中发送信号?
【问题讨论】:
我在 Linux 下有一个简单的程序,它在一个循环中向其子进程发送 SIGUSR1 信号。但是当我发送例如有时会发生 10 个信号,表明孩子只收到了其中的 3 个。最后发送的信号始终是 SIGUSR2,并且每次都会收到。
信号是否在排队,或者当进程没有处理前一个信号时,它只是被覆盖了?有没有办法可以在队列中发送信号?
【问题讨论】:
您的问题可能是 SIGUSR2 是一个立即传递的信号,而其他信号被阻塞或排队(处于待处理状态)。
查看待处理信号的方法如下:http://www.gnu.org/s/libc/manual/html_node/Checking-for-Pending-Signals.html
【讨论】:
会发生以下情况:
一旦信号处理程序处理完信号 nr1,它将处理信号 nr2,然后信号处理程序将处理 SIGUSR2。
基本上,相同类型的待处理信号不会排队,而是被丢弃。不,没有简单的方法可以以这种方式“突发”发送信号。人们总是假设可能有几个信号被丢弃,并试图让处理程序完成清理工作并找出要做什么(例如收割孩子,如果所有孩子同时死亡)。
【讨论】:
如果发送了多个相同类型的信号但未处理,则它们不会排队。说程序屏蔽SIGUSR1,调用kill(getpid(), SIGUSR1) 10 次并取消屏蔽SIGUSR1。它只会收到一次SIGUSR1。
【讨论】:
因此,只有在 struct sigaction sa_flags 字段使用标志 SA_NODEFER 并且从不阻塞信号时,才可以使用 SIGIO 对多个文件进行同时 I/O。
因此,可以从信号处理程序内部获得中断,并为每个正在处理的单独信号创建新线程。这变得复杂了 :) 所以难怪为什么似乎没有人使用 SIGIO。
【讨论】: