信号排队
对于每一个目标进程,内核会用一个bitmap来记录信号的处理状态。如果一个信号还未被目标进程处理,那么它就是挂起/未决(pending)的状态。内核在向目标进程递送信号时,会查看进程对应的bitmap中,该信号对应的bit是否有挂起的信号。
如果当前有挂起的信号,按照Unix传统的做法,内核将直接丢弃这一信号,其结果当然就是该信号不能被目标进程正确接收。这样的信号存在丢失的风险,因而被称为“不可靠信号”。
而后出现的各种Unix衍生版本对此做出了一些改进,以Linux的实现为例,内核会为每个进程维护一组队列(queue),有挂起信号时,就将新来的信号排队(enqueue)。只要挂起的信号个数没有超过内核设定的上限,理论上就不会丢失,这样的信号被称为“可靠信号”。
在代码实现中,bitmap用sigset_t表示,而队列就是一个双向链表,链表头结点包含在进程对应的task_struct中。
struct sigpending {
struct list_head list;
sigset_t signal;};