我遇到了可等待计时器的奇怪行为。如果我用一秒周期创建它,那么在第一次触发后,它的后续触发似乎与某个毫秒值“对齐”,该值与第一次触发有很大不同。
以下是触发时间的示例(小时:分钟:秒.毫秒):
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 的可能值。
相反,您应该通过指定找到合理的开始时间
第一个事件发生的相对时间。
dueTime.QuadPart = -1000000; // 100 ns units, first event at 100 ms from now
绝对时间
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/