5-4 信号的响应过程

come on  !复习一下什么是信号的不可靠?think for a while ???

信号的执行现场是内核帮我们布置的,so  如果一个信号正在执行一个行为,此时不好意思又来了一个这个信号,那么,第一次的行为将会被第二次的行为覆盖。

解决信号的不可靠  ----> 可重入函数:第一次调用未结束,第二次调用就来了,但是不会报错;

所有的系统调用都是可重入的  ,一部分库函数也是可重入的

eg:open read memcpy  rand   很多很多······

int rand(void):  不可重入: 产生伪随机数列,每一个值都是有前一个数通过某种计算得出来的。如果我在产生第N个值的时候呢,rand又被谁谁谁调用  ,那么第N+1个的值 就会有出入咯

可重入函数====》 int rand_r(unsigned int *seedp): 那么所有为随机数列都是通过seedp这个值计算出来的

_r版本:可重入函数

信号的响应过程

内核每秒都会产生若干个中断。信号同收到到响应有一个不可避免的延迟。

过程:内核为每一个进程维护了两个位图:

mask(信号屏蔽字):当前信号的状态(初始为1,信号行为执行完为0) 

pending信号标志位(初始为0 ,信号来了为1)

程序现象:

1.main开始执行  打印 * * *

2.ctrl+C到来  打印  !

3.继续打印  * * * *  直到程序结束

具体执行步骤:

1.  * * *

2.ctrl+c到来--->pending某位 = 1

3.直到等到内核中断来了(内核每秒都会产生很多中断)

4.抱着现场扎内核:  内容:包括返回地址address ----指向-->main 函数的某个位置

5.在等待调度的就绪队列当中,很多进程在排队----->轮到你了

6.从kernal 扎回user 的过程中  : mask & pending   ====   1 & 1   某位为1  其他位为0 ,signalnum  ==== SIGINT

7.将mask = 0 pending= 0 地址address 更换为信号处理函数的地址handler

8. 打印 ! 信号处理程序执行完

9.回到内核  替换地址 :信号处理函数的地址handler    更换为   main 函数的某个位置

10. mask = 1 ;

11.从kernal 扎回user 的过程:    mask   1   & pending   0   处理函数执行完了 

12.继续打印 * * * *

忽略信号   : 

信号的mask位置为 0   不能阻止信号来,但是可以阻止信号是否被响应

mask   pending

1            0   //初始   ---》中断来了(pending=1)---》扎内核---》保存现场:地址---》调度----》kernal扎回user ----》mask & pending-------》

1            1   // mask & pending = 1 --------》

0            0   //mask = 0  pending = 0-----》去执行handler函数 ------》

1            0   // mask = 1    pending = 0------》kernal扎回user ----》mask & pending-------》

原文地址:https://www.cnblogs.com/muzihuan/p/4660253.html