Linux.13_进程信号(重点总结)
文章目录
一、基本概念
1.生活角度
中午11点了,你给自己和女朋友在网上点了两份外卖,你吃米饭,她吃面条。虽然外卖没有到来,但你清楚的知道外卖来临时,你该怎么处理。也就是你能“识别外卖”。
当外卖小哥到了你楼下,你也收到通知,但是你正在CSDN学习,需3min之后才能去取外卖。那么在这3min之内,你并没有下去去取外卖,但是你是知道有外卖到了。也就是取外卖的行为并不一定要立即执行,可以看做“在合适的时候去取”。
在接到电话,再到你拿到外卖期间,有一个时间窗口。在这段时间你并没有拿到外卖,但是你知道有外卖到了。本质上是你“记住了有一个外卖要去取”
当你时间合适,顺利拿到外卖之后,就要开始处理外卖了。而处理外卖一般方式有三种(信号递达):
- 执行默认动作->打开外卖,干饭咯;
- 执行自定义动作->把米饭留给自己,面条给女朋友,干饭
- 忽略->外卖拿回来之后,放一边,先学完下一章节的内容再吃
外卖到来的整个过程,对你来讲是异步的,你不能准确断定外卖员什么时候给你打电话。
2.技术应用角度
用户按下Ctrl-C ,这个键盘输入产生一个硬件中断,被OS获取,解释成信号,发送给目标前台进程,前台进程因为收到信号,进而引起进程退出。
信号:进程间事件异步通知的一种方式,属于软中断。
二、 信号处理
1.信号递达
合适的时间:从内核切换为用户态。
- 默认:执行该信号的默认处理动作。
- 忽略:忽略此信号。
- 自定义:提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号。
2.产生信号的四种方式
- 通过终端按键:Core Dump
- 调用系统函数向进程发信号:kill
- 由软条件产生信号
- 硬件异常产生信号
3.阻塞信号
- 实际执行信号的处理动作称为信号递达(Delivery)
- 信号从产生到递达之间的状态,称为信号未决(Pending)。
- 进程可以选择阻塞 (Block )某个信号。
- 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
- 阻塞和忽略不同,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作
- 阻塞->不处理,忽略->处理方式
- 无论是阻塞还是忽略,信号依然可以添加到未决信号集合中
- SIGSTOP/SIGKILL信号无法被阻塞,无法被自定义,无法被忽略
4.捕捉信号
信号处理过程:
- 使用signal函数进行信号捕捉函数修改时,可以指定SIG_IGN设置为忽略处理
- 自定义处理方式的信号会返回用户态执行信号捕捉函数
- 未决信号是在从程序运行在内核态返回用户态的时候进行处理
- 只有自定义处理方式的信号会在用户态进行处理
- 自定义处理方式的信号会在执行完信号捕捉函数后先返回内核态
5.无法被杀死的进程
- 这个进程阻塞了信号
- 用户有可能自定义了信号的处理方式
- 这个进程有可能是僵尸进程
- 这个进程当前状态是停止状态
因为:
1.信号被阻塞,则暂时不被处理(SIGKILL/SIGSTOP除外,因为无法被阻塞);进程被阻塞,信号会打断进程当前的阻塞状态去处理信号。
2.自定义处理之后,信号的处理方式不再是进程退出
3.僵尸进程因为已经退出,因此不做任何处理
4.进程停止运行,则将不再处理信号
三、可重入
在一个函数中若对局部变量进行了原子操作,则这个函数一定是不可重入的。
- 函数不可重入指的是函数中可以在不同的执行流中调用函数会出现数据二义问题。
- 函数可重入指的是函数中可以在不同的执行流中调用函数而不会出现数据二义问题。
问题小结
上面所说的所有信号产生,最终都要有OS来进行执行,为什么?OS是进程的管理者
信号的处理是否是立即处理的?在合适的时候
信号如果不是被立即处理,那么信号是否需要暂时被进程记录下来?记录在哪里最合适呢?
一个进程在没有收到信号的时候,能否能知道,自己应该对合法信号作何处理呢?
如何理解OS向进程发送信号?能否描述一下完整的发送处理过程?