【Linux】进程信号-3. 信号的保存

3.1 信号其它概念

  • 实际执行信号的处理动作称为信号递达(Delivery)
  • 信号从产生到递达之间的状态,称为信号未决(Pending)。
  • 进程可以选择阻塞 (Block )某个信号(屏蔽)被阻塞的信号将保持在未决状态(保存),直到进程解除对此信号的阻塞,才执行递达的动作。
  • 注意:阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

那上述概念在OS中是如何实现的呢?
每个进程在PCB中都维护了三张表:block、pending、handler。

在这里插入图片描述
该三张表就可完成信号的识别、保存和处理工作;handler表中的初始内容,就是程序员内置的特性(信号处理方式)。
在这里插入图片描述

因此,关于信号的所有操作,都是围绕这三张表开展的,要横着看这三张表。

3.2 信号操作函数

  1. 操作sigset_t 类型的数据

在这里插入图片描述

  • 注意,在使用sigset_ t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。初始化sigset_t变量之后就可以在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号了。
  • 这四个函数都是成功返回0,出错返回-1。sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1。

sigset_t类型的定义如下:
在这里插入图片描述
未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),

  1. 设置进程的block表

sigprocmask:读取或更改进程的信号屏蔽字(阻塞信号集)。

在这里插入图片描述

对于参数how,有以下三个选项:
在这里插入图片描述

  • 如果oldset是非空指针,则读取进程的当前信号屏蔽字通过oldset参数传出。
  • 如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。
  • 如果oldset和set都是非空指针,则先将原来的信号屏蔽字备份到oldset里,然后根据set和how参数更改信号屏蔽字。
  1. 获取当前进程的pending信号集

sigpending:读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。

在这里插入图片描述

下面我们做一个简单的例子来验证上面的函数:

  • 先将2号信号屏蔽
  • 打印pending信号集
  • 发送2号信号,但信号不递达

在这里插入图片描述

在这里插入图片描述

你是否有这样的疑问: 为什么只给我提供了操作block信号集的方法,没有提供pending与handler表的方法呢?
在信号的产生那里,操作的全是pending表;signal(signum,handler)函数操作的handler表。

上一篇:智慧物流与人工智能AI深度结合应用思考


下一篇:计算机网络中的数据包传输机制详解