调用睡眠的程序不会在信号上唤醒

Posted

技术标签:

【中文标题】调用睡眠的程序不会在信号上唤醒【英文标题】:program calling Sleep doesn't wakup on signals 【发布时间】:2017-05-24 11:06:42 【问题描述】:

在 Linux 中,当调用 'sleep' 的执行线程暂停其执行时。一旦向进程发送信号,“睡眠”函数就会立即返回。我可以安装我的信号处理程序并正确设置下面的标志以退出 while 循环。

// a signal handler set 'flag' on CTRL-C

while(flag) 
   sleep(10); // returns on signal caught

在 Windows 中,我看不到这一点。我正在使用“睡眠(DWORD 毫秒)”并且我已经使用“信号”功能安装了我的信号处理程序。基本上,睡眠线程仅在“睡眠”结束时恢复。

我必须做些什么才能让“睡眠”在我的代码中返回? 我是在使用正确的方法(使用标志退出 while 循环)还是必须查看其他内容?

【问题讨论】:

我什至不知道 WIndows 有 *nix 风格的信号 :( ..不,无论您在做什么,轮询标志都不是正确的方法。它浪费了 CPU 并增加了可避免的延迟(在您的情况下平均为 5 毫秒)。 Windows 有很多同步对象。信号量等待几乎肯定会起作用。 另外,标志需要是易变的。忘记标志,阅读 Windows 同步并正确执行:) 使用 SleepExbAlertable=TRUE 并在插入 APC 时返回函数。如果你直接使用ZwDelayExecution(这个api并调用Sleep[Ex])你也可以通过警报来打破等待 - ZwAlertThread 一旦你停止调用睡眠,那么事情会为你寻找 【参考方案1】:

您应该使用event object。

将循环替换为对WaitForSingleObject 的调用,并让 control-C 处理程序调用SetEvent。

(当然,在实践中,您不太可能真的希望您的程序坐下来等待,什么也不做,直到用户按下 control-C。但这就是问题所呈现的场景,这个答案为您提供了一个起点用于更真实的场景。)

【讨论】:

以上是关于调用睡眠的程序不会在信号上唤醒的主要内容,如果未能解决你的问题,请参考以下文章

从睡眠中唤醒主线程

使用信号从睡眠中唤醒进程

通过信号SIGQUIT唤醒睡眠守护进程

linux内核之系统调用nanosleep与pause()

解决mac睡眠唤醒/插拔之后,外接显示器无法点亮/无信号问题

睡眠命令后唤醒Windows系统的命令