引出问题
可能很多人和我一样,在学习APUE第10章信号章节时存在很多疑惑,究其原因可能是APUE没有对信号的生命周期有个详细明了的解释导致的。本文是通过网上的文章整理而成,正确与否,还望批评指正!
信号的同步和异步产生
注意,这里的“同步”和“异步”描述的是信号的产生方式。
在绝大多数人的知识储备中,都认为信号是典型的异步事件,即进程无法预知信号到来的准确时间。但实际上,信号也是可以同步产生。
异步方式产生信号是最常见的,可以通过一个进程发送信号给另一个进程,或者内核检测到某个事件而给进程发送信号,不管何种方式,他们都与当前进程的实际执行毫无关系。例如,用户按下CTRL+C字符,或者子进程结束时内核给父进程发送SIGCHLD信号。
然而,在另外一些情况下,信号的产生却是进程自己产生的,或者说信号的产生与进程自身的执行有关。例如:
(1)由硬件异常产生的信号(SIGBUS,SIGFPE,SIGILL,SIGSEVE,和SIGEMT)。它们都是进程自身执行了特定的非法指令导致的硬件异常。
(2)进程通过系统调用raise(),kill(),或者killpg()向自己发送信号。
在这些情况下产生的信号就是同步的,他们会立即递达给进程(除非进程之前阻塞了它们)。换句话说,同步发生的信号是可预知的、可重现的。
信号的生命周期
关于信号的生命周期,我绘制了一张图如下:
信号从产生到结束的过程
在解释上图之前,我们先了解下什么是信号集?
顾名思义,信号集就是用来表示多个信号的数据结构,其系统数据类型为sigset_t。POSIX.1定义了几个函数来初始化信号集以及增删特定信号的操作函数,详细请man 3 sigsetops.
好了,知道了信号集的概念后,我们来解释下上图,上图过程可以用man 7 signal中的一段话来形容:
A signal may be blocked, which means that it will not be delivereduntil it is later unblocked. Between the time when it is generated and when it is delivered a signal is said to bepending.
Each thread in a process has an independentsignal mask, which indicates the set of signals that the thread is currently blocking. A thread can manipulate itssignalmaskusing pthread_sigmask(3). In a traditional single-threaded application, sigprocmask(2) can be used to manipulate thesignal mask.
信号的产生:信号的产生(generation)原因很多,这里不再赘述。
信号的递达:实际执行信号的处理动作称为信号的递达(delivery)。
信号的未决:信号从产生到递达之间的状态称为信号的未决状态(pending)。
一个进程可以通过信号屏蔽字(signal mask)来有选择地阻塞(block)某个信号 -- 被阻塞的信号在产生后将保持在未决状态,直到进程解除对该信号的阻塞后才执行递达的动作。
由此我们可以得出以下结论:
在《Linux C编程一站式学习》中有个图能很好的解释上述这些概念:
信号在内核中的表示示意图
在上图的例子中,
总结一下:
在信号的生命周期中,信号的未决是一种状态,指的是从信号的产生到递达信号这段时间内信号的状态,而信号的阻塞更像是一个开关,用来决定当信号处于未决状态时是否递达信号。注意,信号的阻塞容易让人产生误会,让人误认为是阻止信号的产生,这种认识是错误的。此外,阻塞和忽略也是不同的概念,忽略指的是当信号递达后可选的一种处理动作。
再来一张网有的图片,很不错。缺点是省略了信号的未决状态。
实时信号和非实时信号
之所以有实时信号和非实时信号的区分,是因为在它们产生(generation)之后,将它们添加到未决信号集中的方式有所区别导致的。
此外,我们需要知道的是,当信号正被递送时,即正在运行信号处理函数时,该信号是被阻塞的(默认情况下,是没有指定SA_NODEFER的)。
参考链接:
http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html 《Linux环境进程间通信(二): 信号(下)》
http://www.cis.temple.edu/~giorgio/cis307/readings/signals.html
http://www.programering.com/a/MjMyADMwATA.html 《Signal Linux system programming》
http://www.filibeto.org/unix/tru64/lib/rel/4.0D/APS33DTE/DOCU_006.HTM
http://m.blog.csdn.net/blog/hanqing280441589/43876983 《Linux信号实践(3) --信号内核表示》
http://www.cnblogs.com/lienhua34/p/4072417.html 《UNIX环境编程学习笔记(24)——信号处理进阶学习之信号集和进程信号屏蔽字》
http://blog.csdn.net/qq276592716/article/details/7325216 《Linux内核信号处理机制介绍》
http://blog.csdn.net/bullbat/article/details/7840405 《Linux信号机制概述》
http://m.blog.csdn.net/blog/wwangfeng2500/7649102# 《Linux内核信号处理机制介绍》