windows - 奇怪的可等待计时器 "aligning"问题

标签 windows winapi visual-c++ timer

我遇到了可等待计时器的奇怪行为。如果我用一秒周期创建它,那么在第一次触发后,它的后续触发似乎与某个毫秒值“对齐”,该值与第一次触发有很大不同。

以下是触发时间的示例(小时:分钟:秒.毫秒):

18:06:25.753  <-- here 753
18:06:26.238  <-- here and later 238
18:06:27.238
18:06:28.238
18:06:29.238

如果我重新运行程序,第一次触发的毫秒值会有所不同,但后续事件会在 238 值处再次发生。

这是我使用的测试代码:

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
    LARGE_INTEGER dueTime;
    dueTime.QuadPart = 0;
    SetWaitableTimer(hTimer, &dueTime, 1000, NULL, NULL, FALSE);

    for (int i=0; i<10; i++)
    {
        WaitForSingleObject(hTimer, INFINITE);

        SYSTEMTIME st;
        GetLocalTime(&st);
        printf("%02d:%02d:%02d.%03d\n", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    }

    return 0;
}

我在 Windows 7 和 Windows Server 2008 R2 中看到此问题,但在 Windows XP/Server 2003 中没有。

谁知道为什么会发生这种情况?我可以想象这可能是一些系统优化来减少计时器中断和/或上下文切换。但我在任何地方都找不到它的记录。这是意想不到的,可能会导致问题。

最佳答案

dueTime.QuadPart = 0;

您发表此声明的目的是什么?

文档说:“正值表示绝对时间。”和“负值表示相对时间。”。零从不指定 dueTime 的可能值。

相反,您应该通过指定找到合理的开始时间

  1. 第一个事件发生的相对时间。

    dueTime.QuadPart = -1000000; 
    // 100 ns units, first event at 100 ms from now
    
  2. 绝对时间

    FILETIME FileTime;
    LARGE_INTEGER dueTime;
    
    GetSystemTimeAsFileTime(&FileTime);
    CopyMemory(&dueTime,&FileTime,sizeof(FILETIME));
    dueTime.QuadPart += 1000000; 
    // 100 ns units, first event at 100 ms from FileTime
    

注意:可等待定时器允许以 100 ns 为单位指定到期时间。这并不意味着它们可以以这种精度触发。精度由系统时间粒度决定。有关系统时间粒度的更多详细信息可以在 this 中找到。回答。

关于windows - 奇怪的可等待计时器 "aligning"问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21384733/

相关文章:

c++ winrt uwp 如何从依赖属性中获取值

c++ - 标题栏中的汉字

c++ - 用于 DNS 更改通知的 Windows API

c - 将结构传递给 C 中的函数

c++ - Windows 7 如何确定您是否需要管理员权限? (vc60)

python - PyGTK 窗口始终位于所有 'always on top` 窗口之上

c++ - UXTheme:绘制无边框的组合框雪佛龙

visual-c++ - 错误 C2653 : 'boost' : is not a class or namespace name VC++ 2008 express

c++ - 如何使用SendMessage设置图片框样式

android - 在 Windows 中从 Jenkins 启动 android 模拟器 adb(运行仪器测试,模拟器不会出现)