10.4 不可靠信号

在早期版本的UNIX系统中(比如说版本7),信号是不可靠的,意思是说信号可能丢失:一个信号出现,但是进程可能永远也不知道它,Aslo,a process had little conrol over a signal: a process could catch the signal or ignore it, 有时候,我们希望告知内核阻塞一个信号:不要忽略它,当信号出现的时候记住,然后在进程准备好以后通知进程。

在4.2BSD中做了修改,从而提供了一种称为reliable signals的东西,在SVR3上也做了另外一套修改,在System V上提供了可靠信号,POSIX.1最后选择了BSD模型来进行标准化。

使用早期版本信号处理的一个问题是:在每一次信号出现以后,信号的处置方式就会被恢复到其默认处理方式(在前一个例子中,我们仅仅运行每个信号一次,所以避免了这个问题。),描述这些早期系统的一个典型例子关注了如何处理中断信号。其代码描述看起来像如下所述:

 
 
  1. int sig_int(); /*my signal handling function*/
  2. ...
  3. .signal(SIGINT, sig_int); /*establish handler*/
  4. ...
  5. sig_int()
  6. {
  7. signal(SIGINT, sig_int); /*establish handler for next time*/
  8. ... /*process the signal*/
  9. }

signal 处理函数被声明为返回一个整形值的原因是:早期系统并不支持ISO C的void数据类型.
上述代码片段的问题是:在信号已经生成一次之后,但是在调用signal handler里面的signal函数之前,就会存在一个时间窗,在这个时间窗内,如果再出现一次中断信号,那么新出现的信号就会造成一次默认处理,导致进程被终止,虽然在许多时候进程工作看起来是很正常的,但是这只是一个假象。

这个早期版本的系统的另一个问题是:进程不能够关闭信号,即是进程不想改信号出现,所有进程可以实现的是忽略信号。有些时候我们想要告知系统:防止如下信号终止当前进程,但是如果他们出现的话请记住。阐述这一流程的典型事例如下所示:

 
 
  1. int sig_int(); /*my signal handling function*/
  2. int sig_int_flag; /*set nonzero when signal occurs*/
  3. main()
  4. {
  5. signal(SIGINT, sig_int); /*establish handler*/
  6. ...
  7. while(sig_int_flag == 0)
  8. {
  9. pause(); /* go to sleep,waiting for signal*/
  10. }
  11. ...
  12. }
  13. sig_int()
  14. {
  15. signal(SIGINT, sig_int); /*reestablish handler for next time*/
  16. sig_int_flag = 1; /*set flag for main loop to examine*/
  17. }

在此,进程调用函数pause来将自身放到sleep状态中去,直到捕获到信号,但信号出现的时候,信号处理函数会设置标志sig_int_flag位一个非零值。在信号处理函数返回之后,进程被内核自动唤醒,进程检查到标志值非零,于是开启执行其计划的事情,但是存在一个时间窗可能使得事情变得非常糟糕,如果信号出现在检查sig_int_flag之后但是有恰巧在pause之前,进程就可能永远不能唤醒了(假设信号从此不再产生),那么该信号的出现就丢失了,这是一些代码出现错误的例子,虽然在很多时间看起来是正确的,但是这只是一个假象,调试这种类型的错误是非常困难的。





转载于:https://www.cnblogs.com/U201013687/p/5518331.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值