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-------》