信号---信号的阻塞

来源:互联网 发布:索信达数据 编辑:程序博客网 时间:2024/05/19 12:17

一、信号在内核中的表示
1.首先我们来了解几个基本的概念

  • 信号的递达(Delivery):实际执行信号的三种处理动作;
  • 信号的未决(pending):信号从产生到递达之间的过程;
  • 阻塞信号(Block):被阻塞的信号产生时将保持在未决的状态,直到进程解除对此信号的阻塞,才会执行递达动作;

2.阻塞和忽略的区别
忽略是信号默认处理动作的一种,即信号的递达,而阻塞是信号未决的状态,只有解除阻塞,才能达到递达状态,即处理信号

3.进程中每个信号都有两个标志位,即阻塞(Block)和未决(pending),还有一个函数指针表示处理动作(handler),他们存储在进程的PCB中,struct sigpending pending;字段就是存放信号的信号表。
这里写图片描述
其中一旦信号被block,当有信号产生的时候会一直pending,因为未决就是未处理的意思,block到不了就处理不了,pending会一直有该位

因为PCB中使用32位来表示上图中的block和pending表所以非实时信号就算发送多个,也只显示一个。实时信号会排队,有几个来就有几个排队(链表形式)

block表:某位为0表示该位对应标号的信号未被阻塞,为1表示阻塞

pending表:某位为0表示信号还未产生或者已经被处理

上图中2号信号两个表同时为1表示产生了2号信号,但因为2号信号被阻塞所以一直未决。

4.介绍一个概念信号集
信号集,即sigset_t,阻塞和未决信号都用bit位表示,用相同的类型sigset_t存储

二、信号集的操作函数
这里写图片描述
sigemptyset:初始化set所指向的信号集,使其所有的对应bit位清零,表示该信号集不包含任何有效信号
sigfillset:初始化set所指向的信号集,使其所有信号的对应bit位置1,表示该信号集有效信号包括系统支持的所有信号
sigaddset:在信号集中添加有效信号,signo是信号编号,set表示信号集
sigdelset:在信号中删除有效信号
sigismember:判断一个信号集的有效信号中是否包含某种信号

注意:我开始不太懂,我们定义一个信号集sigset_t block;为什么用sigemptyset函数初始化信号集,然后添加我们要阻塞的信号后,还需要再次调用sigprocmask函数来对信号集操作(读取或更改信号屏蔽字),我们定义了一个信号集合block表示阻塞信号集,这只有我们知道,操作系统是不知道的,操作系统只知道block是一个信号集,至于它是一个信号屏蔽字还是未决信号集操作系统是不知道的,只有通过调用sigprocmask函数和sigpending区分

三、sigprocmask函数(读取或更改进程的信号屏蔽字)
这里写图片描述
这个函数的作用是将指定信号集和set加入到进程的阻塞信号集中

参数情况:
1.how参数

  • SIG_BLOCK:set的信号屏蔽字的内容添加到当前的信号屏蔽字
  • SIG_UNBLOCK:set包含的信号屏蔽字的内容从当前的信号屏蔽字中删除
  • SIG_SETMASK:设置当前信号屏蔽字为set所指向的值

2.set和oset参数

  • 如果oset为NULL,即读取当前的信号屏蔽字并通过oset传出
  • 如果set是非NULL,则更改当前进程的信号屏蔽字按照参数how修改
  • 如果oset和set都是非NULL,则先将原来的信号备份到oset,然后根据set和how参数更改信号屏蔽字

3.如果调用sigprocmask函数解除若干个处于未决状态信号的阻塞,则在sigprocmask返回前,至少有一个信号递达

四、sigpending(读取当前信号的未决信号集,通过set传出)
这里写图片描述

代码验证:(对SIGINT信号添加到block信号集中,并且将信号集以阻塞的形式添加到当前的进程的信号屏蔽字中,当产生SIGINT信号,我们可以看到未决表2号信号为1,其余都是0)
这里写图片描述
这里写图片描述

结果:
这里写图片描述

0 0