【linux进程信号(二)】信号的保存,处理以及捕捉
💓博主CSDN主页:杭电码农-NEO💓
⏩专栏分类:Linux从入门到精通⏪
🚚代码仓库:NEO的学习日记🚚
🌹关注我🫵带你学更多操作系统知识
🔝🔝
进程信号
- 1. 前言
- 2. 信号阻塞,信号递到和信号忽略
- 3. 进程是怎样保存信号的?
- 4. 信号集操作函数
- 5. 进程是如何捕捉信号的?
- 6. 总结
1. 前言
上一篇文章了解到信号产生的四种方式,
但是信号产生后,然后呢?需要对信号
进行保存,最后对信号进行处理
如果你没有阅读过前一篇文章,或者不知道信号的默认处理方式,请先阅读这篇文章: 信号的基本概念
本章重点:
本篇文章着重讲解信号保存的方式以及
周边概率,信号阻塞,信号递达.理解
信号处理的默认方式,如何修改默认方法
最后会讲解进程是如何捕捉信号的?
2. 信号阻塞,信号递到和信号忽略
在讲解进程是如何保存信号之前,要
先了解下面几个概念:
- 信号递达:
实际执行处理信号的动作叫做信号的递达
- 信号的未决状态:
在信号产生到信号递达之间的状态叫做信号的未决状态
- 信号阻塞:
一旦一个信号被设置了阻塞之后,那么此进程就不会收到此信号
- 信号忽略:
一旦一个信号被设置为忽略,那么当这个信号来临后,进程不会对此信号做处理
- 阻塞和忽略的区别:
一个信号被阻塞后,它就不会递达,而忽略是指信号递达后,执行的动作是什么都不做
3. 进程是怎样保存信号的?
在进程的PCB中,存在三张和信号相关的表
更准确的讲,前两个结构是位图,最后一个是表(数组).
- block位图:
这个位图代表,在这个进程中,有哪些信号是被阻塞了的?位图的第一个元素为0,代表1号信号没有被阻塞,第n个位置为1,代表n号信号被阻塞了,也就是说0/1代表某个信号是否被阻塞,这个位图又被称为信号屏蔽字
- pending位图:
这个位图是进程存储信号的结构,位图中的第n个位置为0/1代表是否收到了n号信号,如若收到,会在后续进行处理,这个位图又被称为信号集
- handler数组:
首先,这个数组是一个函数指针数组,里面存储的是函数的地址,数组的n号元素存储的函数地址代表收到n号信号之后,要去处理信号时,需要调用的函数.在上图中,SIG_DFL宏代表这个函数就是此信号的默认处理函数,SIG_IGN宏代表收到这个信号后,直接忽略此信号,当然我们也可以自己写一个函数来充当信号的处理方法,这个后面会讲
4. 信号集操作函数
首先我想隆重介绍的是signal函数:
第一个参数代表要设置几号信号
第二个参数代表,信号到来需要调用哪个函数
下面可以进行一个简单的编码验证:
void mycatch(int signum) { cout signal(SIGINT,mycatch);//既可以填写定义的宏,也可以直接写数字 while(1) { cout for(int i=1;i if(sigismember(&tmp,i)) cout sigset_t bset; sigemptyset(&bset); sigaddset(&bset,sig); int n = sigprocmask(SIG_BLOCK,&bset,NULL);//只对sig号信号屏蔽 assert(n==0); cout cout sigpending(&pending); showpending(pending); sleep(1); } return 0; }