信号概念
信号就是用来通知打断当前操作,告诉他某件事情发生了,去做另一件事
信号的实质PCB表中的两个位图和指针数组
这两个位图是 blocked 阻塞位图 pending 未决位图 handler 信号递达指针
在这之前,我们需要了解一下什么叫信号的递达,信号的未决,信号的阻塞
- 信号的递达就是对信号进程处理
- 信号的未决就是指信号从产生到递达的过程就叫未决
- 信号的阻塞不是指信号等待,而是阻止信号的递达
信号的产生
信号的产生有三种
硬件中断:例如ctrl + c 向进程发送 2 号信号
硬件异常: 如非法内存访问,cpu处理出错
命令产生:kill 命令
系统函数:kill 对任意函数发送信号 raise(signo) 对自己发送信号 abort()对自己发送一个信号 alarm()时钟调用
信号的处理
信号有三种处理方式
默认处理方式:按照系统默认的方式处理
忽略处理:直接将信号注销掉
自定义处理方式:按照用户自定义的方式处理
信号的生命周期
信号的产生->信号的注册->信号阻塞->信号注销->信号递达
信号的分类
信号分为可靠信号和非可靠信号
我们可以在命令行输入kill -l 查看
其中1~31共31个是不可靠信号
34~64共31个是可靠信号
其中不可靠信号是系统处理的,可靠信号是用户设置处理的
其中可靠信号和不可靠信号的区分就在于信号是怎样注册和注销的
当可靠信号到来时,在pending位图中,不管该信号是否已经存在,直接将计数+1,当该信号注销时,先将信号计数-1,再决定是否删除该信号
当不可靠信号到来时,在pending位图如果已经存在,则直接将该信号丢弃,如不存在则将该信号置1,注销信号时直接将该信号注销掉
信号捕捉流程
在信号捕捉流程中我们发现处理自定义信号的时候会有一次用户态和内核态之间的切换,在这里很容易发生一些事故
这个涉及到了可重入函数和不可重入函数
想想,如果在自定义信号处理函数中对主函数中某个变量发生了变化,那么这势必会影响到主函数的执行结果,所以我们在这里一定要注意可重入函数和不可重入函数
可重入与不可重入函数的区别
如果函数对全局变量或者对malloc/new出来的空间进行操作或是标准IO库进行操作,那么这个函数就是不可重入函数
反之就是可重入函数