一.由软件条件产生信号
通过管道进行通信时,有一条原则,当读端进程关闭,OS会关闭掉写端进程,怎么关闭的呢?发送13号信号给写端进程,进程收到信号以后,就把自己关闭。由于管道是文件,属于软件范畴,所以这儿就叫做由软件条件产生信号。

1.alarm函数
这儿有个系统调用------alarm,可以为当前调用该函数的进程设一个闹钟,待设置的时间到了以后,OS会给该进程发一个信号。 该信号的默认处理动作是终止该进程。
我们来检验一下,发的是几号信号:


答案是14号信号。
2.pause函数
让当前进程暂停。

3.快速理解系统闹钟(alarm的底层原理)
OS内存在多个进程,所以每个进程都可以设置闹钟(调用alarm),所以OS会同时存在多个闹钟,想要管理那么多个闹钟,就会请到我们的老朋友------先描述再组织。
描述:

每设定一个闹钟,就生成一个timer_list。
组织:
将每一个上面那种闹钟节点,push_back进一个小堆,堆顶的节点,就是超时时间expires最短的那一个。

会让当前时间与堆顶超时时间做对比,当前时间等于超时时间以后,会让堆顶的闹钟节点出堆,并执行相应的处理方法(即执行函数指针function指向的函数),而这个执行方法,就是向对应进程发送14号信号SIGALRM;然后再对堆进行调整。
闹钟的一切都属于软件的范畴,而发送信号的条件是超时(时间超过expired),所以闹钟函数发信号就是由软件条件产生信号!
二.信号的保存
当前进度:

我们之前粗浅的知道,信号是靠task_struct里,位图上的比特位来保存是否收到信号。现在来深度解析一下信号的保存。
1.概念补充

2.概念在内核中的具体表现------三张表------block,pending,handler
进程PCB里与信号相关的,不止一张保存是否收到信号的位图表pending,还有其余两张表:


注意:
1.9号信号不可被捕捉,不可被阻塞!
2.准备递达时,要先将pending中对应的信号的比特位,由1->0。
谈谈handler
Ⅰ.signal函数(自定义捕捉)修改递达方案,本质上就是修改handler的内容。
Ⅱ.那上面图中handler里的SIG_DFL和SIG_IGN是个什么?
答案是递达方案,SIG_DFL是默认(默认一般是终止),而SIG_IGN是忽略。
从类型上来说,它们是宏,将整形强转成函数指针数组类型的宏:


3.附录------细节补充
①.如果在进程解除 对某信号的阻塞之前 这种信号产⽣过多次 ,将如何处理?POSIX.1允许系统递送该信 号⼀次或多次。Linux是这样实现的:常规信号 在递达之前产⽣多次只计⼀次,⽽实时信号在递达之 前产⽣多次可以依次放在⼀个队列⾥。本章不讨论实时信号。
②.进程终止的方式有两种,Core和Term,这里来看看它们的区别。

但在云服务器上,核心转储是被禁止的,原因在于云服务器业务程序崩溃后,监控脚本会自动重启;如果程序有bug反复崩溃,会源源不断生成core文件,短时间耗尽磁盘,导致整个服务器业务瘫痪。
当然,是可以打开core dump的,只需要输入指令:ulimit -c + 文件大小 就可以了。
为什么要有核心转储呢?

