如何正确调用 SetWaitableTimerEx
Posted
技术标签:
【中文标题】如何正确调用 SetWaitableTimerEx【英文标题】:How to call SetWaitableTimerEx correctly 【发布时间】:2015-09-23 21:29:46 【问题描述】:我们在 Boost.Thread 中有一个长期存在的错误报告,其中显然线程睡眠会在计时器结束时将计算机从睡眠中唤醒 (https://svn.boost.org/trac/boost/ticket/11368)。这显然是由于新使用了SetWaitableTimerEx()
来实现合并计时器支持,我们用REASON_CONTEXT
调用它,如下所示:
REASON_CONTEXT default_reason_context=0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic";
如果定时器触发导致 PC 从睡眠中唤醒,它肯定与这个 REASON_CONTEXT
值有关。
这里有人能告诉我们在定时器到期时不让 PC 从睡眠中唤醒的适当值吗?
【问题讨论】:
当文档看起来很奇怪时,请务必查看实际的 SDK 声明。如果您使用 VS,请右键单击 > 转到定义,您将进入 WinBase.h。您会看到 WakeContext 参数实际上是__in_opt
,而不是 MSDN 文章中建议的 _IN
。美元换甜甜圈,你可能会更喜欢 NULL。
我们从反汇编中知道,为 WakeContext 指定 NULL 会导致调用 SetWaitableTimer() (即禁用合并计时器支持)。如果预期的睡眠时间超过几秒钟,我想这可能没问题?
【参考方案1】:
根据 Microsoft 的这份文档:Windows Timer Coalescing,第 8-9 页:
SetWaitableTimerEx 有两个新参数:WakeContext 和 TolerableDelay。 WakeContext 参数仅在您设置可以将系统从睡眠状态唤醒的计时器时使用。
看起来为WakeContext
参数传递NULL
很好,这是SetWaitableTimerEx
不会唤醒系统的唯一方法。定时器合并应该仍然有效。
我在 Windows 10 中尝试过,它似乎可以正常工作。它不会唤醒系统,看起来也不像是在调用SetWaitableTimer
。不过,在旧版本的 Windows 中可能会有所不同,我还没有测试过。
【讨论】:
看起来我错过了该文档中的那一段。谢谢!以上是关于如何正确调用 SetWaitableTimerEx的主要内容,如果未能解决你的问题,请参考以下文章