【问题标题】:How to call SetWaitableTimerEx correctly如何正确调用 SetWaitableTimerEx
【发布时间】: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() (即禁用合并计时器支持)。如果预期的睡眠时间超过几秒钟,我想这可能没问题?

标签: winapi timer power-management


【解决方案1】:

根据 Microsoft 的这份文档:Windows Timer Coalescing,第 8-9 页:

SetWaitableTimerEx 有两个新参数:WakeContextTolerableDelayWakeContext 参数仅在您设置可以将系统从睡眠状态唤醒的计时器时使用。

看起来为WakeContext 参数传递NULL 很好,这是SetWaitableTimerEx 不会唤醒系统的唯一方法。定时器合并应该仍然有效。

我在 Windows 10 中尝试过,它似乎可以正常工作。它不会唤醒系统,看起来也不像是在调用SetWaitableTimer。不过,在旧版本的 Windows 中可能会有所不同,我还没有测试过。

【讨论】:

  • 看起来我错过了该文档中的那一段。谢谢!
猜你喜欢
  • 2020-08-25
  • 2013-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 2019-08-27
  • 2021-10-28
  • 2016-06-28
相关资源
最近更新 更多