1、信号的入门
1、进程能处理信号的前提------进程能识别信号。
2、信号产生后,进程可能不会立即去处理信号,而是选择适当的时机。
3、信号的产生对进程而言是异步的(随时可以发过来)。
4、信号的处理方式: 执行默认动作、执行忽略信号、执行自定义动作。
5、信号如果无法立即处理,就必须将其记录下来。
信号的基本概念
信号是一种软件中断,当一个进程收到一个信号时,信号就会打断当前进程。
信号的分类: kill -l
Linux 系统当中有62种信号,
不可靠信号:1-31 (非实时信号),信号有可能会丢失。
可靠信号:34-64 (实时信号),信号不会被丢失。
信号的产生方式
信号的产生方式:
硬件产生
ctrl+c : 给进程发送SIGINT信号,这个信号会导致进程退出; 2
ctrl+z :给前台进程发送一个SIGTSTP信号 ,让一个前台进程放到后台,并且进程状态为T ,暂停状态;20
ctrl+ |: 发送-个SIGQUIT信号;3
调用系统函数
向进程发送信号kill函数
abort函数6 SIGABRT
alarm函数
由软件产生的信号
alarm函数14 SIGALRM
信号的注册
换个方式画图理解
在pcb的struct sigpending —> signal(位图) 中标记收到了那些信号;
并且为这个信号组织一个sigqueue结点,添加到链表中
不可靠信号:1-31 判断位图是否为1,为1则什么都不做(事件丢失), 否则添加结点修改位图
可靠信号:34-64 修改位图为1,并且为每个到来的信号都添加一个sigqueue结点,
1.非可靠信号
第一次注册
更改sig位图当中信号对应的比特位,直白点,就是将对应的比特位置位1 ,在sigqueue队列当中添加响应信号的处理节点;
再次注册
背景:还没有来的及处理已经注册的非可靠信号,这会进程又收到了同样的非可靠信号
1.先判断对应信号的比特位是否为1 ,如果为1 ,则不会添加sigqueue节点到sigqueue队列当中去;
为什么1~31是非可靠信号,就是由于”再次注册”的时候,会判断是有已经有该信号了, 如果有,则丢弃新的信号
2.可靠信号
第一次注册
更改sig位图当中信号对应的比特位,直白点,就是将对应的比特位置位1 ,在sigqueue队列当中添加响应信号的处理节点;
再次注册
1判断信号对应的bite位是否为1 ,如果为1 ,则不修改比特位;如果为0,则修改为1 ;
2.修改完比特位之后,还需要添加对应的sigqueue节点到sigueue队列当中去,不管sigqueue当中是否有相同可靠信号的sigqueue节点;
信号的注销过程
非可靠信号的注销
将sig位图当中对应信号的比特位置位0,并且将sigqueue队列当中对应信号的sigqueue节点进行出队操作
出队操作:内核执行相应信号的处理方式
可靠信号的注销
1.判断对应信号在sigqueue队列当中的节点数量
信号节点数据量等于1,将对应信号的比特位置位0,并且将sigqueue队列当中对应信号的sigqueue节点进行出
队操作信号节点数据量等于大于1,就不能将对应信号的比特位置位0 (也就是意味着还是为1 ) , 将对应信号的一个sigqueue节点进行出队操作;
信号的捕捉处理
1.信号都有哪些处理方式
默认处理方式: SIG_ DEL -->执行一 个动作(执行-个函数)
忽略: SIG IGN —> 不干任何事情
子进程退出的时候,会给父进程发送一个SIGCHID ,而操作系统对SIGCHID信号的处理方式为忽略处理,这就导致父进程来不及回收子进程资源。
自定义:程序员自己定义信号的处理函数
函数的处理流程
定义信号的处理流程
1.在task_ struct结构体当中,有一个指向sighand_struct的结构体指针,在该结构体当中有一个action数组,数组当中的每一个元素都是一 个structk_sigation结构体,数组,当中每一个元素对应一个信号的处理逻辑。
2.在struct k_ sigaction结构体当中有一个元素是struct sigaction sa,在struct sigaction结构体当中有一个sighandler_ 类型的元素,这个sighandler_t一个函数指针类型,typedef void (*sighandler)(int), 保存信号默认执行的函数;
操作系统默认对信号的处理
当sig位图当中收到某一个信号的时候,意味着sig位图当中的某一个比特位被置为 了1 ,操作系统处理该信号的时候,就会从PCB当中去寻找sighang_ struct这个结构体的指针,从而找到sa_ handler,进而操作系统内核去调用sa_ handler保存的函数地址。完成信号的功能
自定义信号处理函数
signal :相当于改掉了sa_ handler保存的函数地址,意味着,当收到了自定义信号的时候,操作系统内核会去调用sa_ handler保存的新的函数地址,而这个函数是程序员定义的,也就达到了改信号处理函数的目的
信号的捕捉流程
信号的常见概念
实际执行信号的处理动作称为信号递达(Delivery)
信号从产生到递达之间的状态,称为信号未决(Pending)。
进程可以选择阻塞 (Block )某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作