免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6460 | 回复: 5
打印 上一主题 下一主题

如果nanosleep被用户捕获的信号中断了,能有机会再执行restart syscall吗? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-05 11:26 |只看该作者 |倒序浏览
ULK11章中,如果nanosleep执行时被信号中断,并且这个信号没有被用户cache(也就是执行default/ignore动作)时,
nanosleep会返回ERESTART_RESTARTBLOCK,这样导致nanosleep被重新执行,并且会继续等待剩余的时间。

但如果那个中断系统调用的信号被用户捕获了,则不会让nanosleep继续执行了,而是直接返回-EINTR,请问系统为什么要这样设计呢?至少应该设计成可以让用户定制是否继续执行阿?

论坛徽章:
0
2 [报告]
发表于 2008-09-05 11:38 |只看该作者
EINTR不就是了吗

  EINTR  The pause has been interrupted by a non-blocked signal that was  deliv-
              ered  to  the  process.  The remaining sleep time has been written into
              *rem so that the process can easily call nanosleep() again and continue
              with the pause.

论坛徽章:
0
3 [报告]
发表于 2008-09-07 16:45 |只看该作者
"至少应该设计成可以让用户定制是否继续执行阿?"
如果系统调用返回的错误码为-ERESTARTSYS不就是让根据用户的配置(是否设置SA_RESTART,参看handle_signal()函数)来决定是否重新执行系统调用吗!

对于sys_nanosleep()系统调用,如果被用户的可捕获信号唤醒那肯定不能根据剩余的睡眠时间继续睡眠呀,如果继续睡眠那用户态的信号处理函数什么时候处理?设想你在用户态调用sleep()让进程睡眠但是又向进程发送可捕获的信号来唤醒进程那不就无法完成了吗

论坛徽章:
0
4 [报告]
发表于 2008-09-09 10:27 |只看该作者
原帖由 flw2 于 2008-9-5 11:38 发表
EINTR不就是了吗

  EINTR  The pause has been interrupted by a non-blocked signal that was  deliv-
              ered  to  the  process.  The remaining sleep time has been written into
        ...

谢谢!
也就是说,nanosleep在没有发生自动执行的时候,最终会返回剩余时间,让用户有机会手工继续等待。

但我还是有一点不明白,对nanosleep这一类需要ERESTART_RESTARTBLOCK的函数来说,为什么只有在信号没有被用户捕获的情况下才有机会自动执行呢?
如下表中:
Signal ActionEINTRERESTARTSYSERESTARTNOHANDERESTART_RESTARTBLOCKERESTARTNOINTR
DefaultTerminateReexecuteReexecuteReexecute(sys_restart_syscall)Reexecute
IgnoreTerminateReexecuteReexecuteReexecute(sys_restart_syscall)Reexecute
CatchTerminateDependsTerminateTerminateReexecute

为什么不存在某个系统调用的返回值,让系统调用在被用户捕获的情况下也自动执行呢?
如:
Signal ActionE??????
DefaultReexecute(sys_restart_syscall)
IgnoreReexecute(sys_restart_syscall)
CatchReexecute(sys_restart_syscall)

论坛徽章:
0
5 [报告]
发表于 2008-09-09 10:43 |只看该作者
原帖由 mars007 于 2008-9-7 16:45 发表
"至少应该设计成可以让用户定制是否继续执行阿?"
如果系统调用返回的错误码为-ERESTARTSYS不就是让根据用户的配置(是否设置SA_RESTART,参看handle_signal()函数)来决定是否重新执行系统调用吗!

对于sys_na ...

谢谢!
返回-ERESTARTSYS确实可以让系统调用根据用户的配置重新执行,但这个重新执行与ERESTART_RESTARTBLOCK的重新执行不同。ERESTARTSYS指的是原封不动地重新执行系统调用,假设nanosleep使用了ERESTARTSYS,则会再次等待相同的时间。而ERESTART_RESTARTBLOCK的重新执行意味着通过sys_restart_syscall进行的重新执行,对于nanosleep来说,如果原先等待了30纳秒中的10纳秒,重新执行时会继续等待剩下的20纳秒。

但从ULK11.3中的表中来看,只能设置让系统调用在用户没有捕获的时候通过sys_restart_syscall重新执行,而不能设置让系统调用在用户捕获了信号的时候也通过sys_restart_syscall重新执行。

对于sleep来说,确实需要在得到信号的时候直接退出系统调用而不继续执行,但对nanosleep来说,我觉得是需要在执行完信号处理程序后继续等待完剩下的时间的。而为什么nanosleep的时候,来了用户没捕获的信号就执行默认动作后继续等待,而来了用户捕获的信号就执行回调函数后停止等待了呢?

论坛徽章:
0
6 [报告]
发表于 2008-09-09 11:14 |只看该作者
原帖由 OstrichFly 于 2008-9-9 10:43 发表

谢谢!
返回-ERESTARTSYS确实可以让系统调用根据用户的配置重新执行,但这个重新执行与ERESTART_RESTARTBLOCK的重新执行不同。ERESTARTSYS指的是原封不动地重新执行系统调用,假设nanosleep使用了ERESTARTSY ...


因为如果睡眠某段时间,比如3S,那就是说真是想睡眠3S
然而,程序可能在某些事件(我想,这里其实只有信号)时,程序希望马上相应信号,而不是再睡眠,(当然,如果非要继续睡,那就是程序的策略问题了,也可以手工再继续睡眠),如果信号没被捕获,那和没有信号对进程关注的角度来说是一样的,接着睡吧
而你的想法其实就是把这个再睡眠的策略加入到内核中,提供一种方式告诉内核,说即使我捕获了信号,也继续睡
我想这就是经常遇到的,什么该在内核中,什么该在用户态了,这属于比较典型的不应该加入内核中的策略
因为实在没必要加入内核,再nanosleep就行了,否则内核可能会增加很多只有少数情况才用的系统调用, 很多系统调用也会使得参数增加(比如我有一个fd,希望有时是阻塞的有时非阻塞,我希望read的时候能直接带上,而不是切换模式)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP