Linux信号保存
目录
1.Linux信号中断
2.信号保存
1.Linux信号中断
我们知道信号有信号产生,信号保存,信号处理,我们知道了信号产生的本质都是借助操作系统的手产生的,只有操作系统能深入内核去产生信号,并保存信号。
我们得出一个重要结论:任何信号产生都要借助操作系统。
上一节我们知道了我们除0错位会在CPU上发生溢出导致我们的硬件报错,操作系统知道硬件报错,然后给我们的进程发送信号终止进程。现在我们又有一种我们的错误是野指针问题,我们CPU处理指针的时候会把指令存到寄存器里,然后我们看到*p我们要去MMU查页表,我们发现没有映射关系,写不进去,我们发生硬件报错,操作系统知道硬件报错,又把它终止了。
我们的CPU里有一个CR3存有当前进程的页表,EIP存的是即将执行的指令,IR存的是当前正在执行的指令。
信号产生的方式可能有很多,但是最终给我们进程发送信号的一定是操作系统!有了这个认识,我们怎么理解键盘产生信号呢?键盘是硬件吗?毫无疑问是的!OS要不要知道键盘按下了?要知道,为什么?操作系统是软件和硬件的管理者,即使我们不知道底层是怎么实现的,但是我们要知道它肯定要知道我们的键盘被按下。
其实当我们按下键盘的时候会发生硬件中断,我们操作系统就知道硬件的数据准备好了。
我们看一下我们的全过程:当我们的键盘按下的时候,我们会发生硬件中断,向CPU发送硬件中断,CPU识别自身针脚中具有中断信息,然后CPU执行操作系统中处理键盘数据的代码,OS这时候会停下当前的工作,将数据从外设读到内存,等待进一步的处理。
需要说明的是:几乎每一种设备都要在内核中内置一些处理方法,处理对应设备的中断。
还有不是我们操作系统知道键盘的数据好了,而是键盘上的数据好了告诉我们操作系统,怎么通知的,通过中断通知的。
还记得我们前面说过的我们父进程回收子进程就是回收它的status,里面有他们的退出信息和退出码。
信号有2种终止方式,我们core终止会形成对应的core文件,方便我们进行检查。而我们的term不会,就是退出。总之,我们有一些进程退出是不需要知道为什么的,我们就用term,如果我们要追溯我们进程退出的原因,我们就要用core方式退出。
比如,我们的内存申请失败和野指针,如果你需要知道进程退出的原因,我们就用core终止他们。
2.信号保存
我们先来阐述一些概念:我们知道我们的信号有一个步骤是处理信号,实际执行信号处理的动作称为信号递达。
信号从产生到递达之间的状态,叫做信号未决。
进程可以选择阻塞某个信号。
被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。
注意,阻塞和忽略是不同的,只要信号被阻塞就不会被递达,而忽略是递达之后选择的一种处理方式。
我们梳理一下:1.我们的信号生成的时候就是未决状态。2.检查未决信号,若信号未被屏蔽,从内核态到用户态的时候会处理信号,若信号被屏蔽,则保持未决状态。3.递达之后,可以执行默认的行为,调用自定义的处理函数,或者忽略信号。
信号阻塞就是我们在对应的比特位调整,哪个信号被阻塞就把它从0变成1就可以了。
信号是怎么保存的呢?实际上就是在我们的task_struct的结构体里面存了3张位图,block是阻塞,pending是信号产生,handler是处理,我们横着看过去,就能看到这个信号的阻塞状态,是否产生,还有信号的处理方法。
前面我们说过我们信号产生要通过操作系统就是因为它们都在内核里,只有操作系统可以修改内核。
结合前面的信号屏蔽无法递达,我们可以理解我们的信号产生,保存到处理了。
我们所有对信号的操作都是对内核里这3张表的操作!!!
我们还有一个系统调用可以修改我们的block表。
第一个参数