一、概念和注意点: 实际执行信号的处理动作叫做信号的递达(Delivery)(忽略、默认、自定义) 信号从产生到递达之间的状态叫做信号的未决(Pending) 进程可以选择阻塞(Block)某个信号,被阻塞的信号一直处于未决状态,直到进程解除对该信号的阻塞,信号才能递达。 注意点: 1.信号的阻塞和忽略是两个概念,两者的区别:阻塞是让信号无法递达、但是忽略是信号递达之后执行的一种处理动作。 2.一个信号被阻塞,则一定不会被递达;信号一直保持在未决的状态,除非进程解除阻塞。 3.一定要注意信号递达执行处理动作并非立即;信号只是在合适的时候进行处理,说以说:一个信号是否立即被递达和信号被block没有直接关系;也就是说一个信号产生之后没有被立即递达,不一定说明它是被block了,执行处理动作的时机并非是立即。 总之:一个信号被阻塞,则一定不会被递达,一个信号是否被立即递达,和一个信号是否被阻塞,没有直接关系。 4.如果一个信号产生了被阻塞,那么就会一直保持未决;一个信号没有产生就阻塞,那么当他产生之后也会一直就保持在未决状态。 还需要认识到: pending(未决)实际上是一种中间态,未决实际上是将PCB中的信号字段从无到有。 Delivery(递达)实际上是有点类似于一种结束状态,它让PCB中的信号字段从有到无。 二、信号在PCB中的形式(3张表格) 概念: 1.每一个信号都有两个标志位:block,pending,还有一个函数指针指向处理动作。(横着看) 2.信号产生那么pending中的标志位由0到1,直到信号被处理了之后pending中的标志位由1到0,如果阻塞那么标志位由0到1。 3.最直观看到的是三张表格,block和pending都是使用位图数据结构(4个字节大小,32个位),每个位的位置表示信号编号(从1开始),每个位的内容表示是否block是否pending; 第三张表格是31个元素的函数指针数组。(那么实际上我们对一个信号的捕捉就是使用這个函数指针数组的某个指针指向一个处理函数)(目前我理解是每个PCB的这三张表里面存的是31个普通信号,不包括实时信号)。(竖着看) 注意: 1.操作系统给每个PCB分配一套这三张表。 2.一个进程给另一个进程发送信号本质上是修改进程的pending表格。如果该进程的该信号的位置对应的block没有被设置为阻塞,那么這个信号在合适的位置就有会被递达。 问题:一个信号在递达之前是否可以产生多次?如果可以产生多次那么在信号递达的时候对多次产生的信号处理方式如何? 回答:POSIX标准中是允许一个信号被递送一次或者多次;重点在与普通信号和实时信号的不同。 Linux的实现方式: 普通信号:同一个信号在递达之前如果产生多次,按一次处理。 实时信号:同一个信号在递达之前如果产生多次,就会把信号依次放到一个队列里面。 在对于信号的相关知识有了一定了解了之后我们希望能模拟实现一个信号的阻塞和递达,更加直观的了解信号,么就需要提到一个概念叫做信号集,這个后期的博客再整理。