WaitForSingleObject 的超时分辨率

12
当我使用WaitForSingleObject函数等待非信号事件时,有时会发现在指定的超时时间内返回了WAIT_TIMEOUT。仅将超时设置为1000ms并循环调用该函数,我曾经看到调用在不到指定时间的情况下返回了(在WinXP运行)。我正在使用QueryPerformanceCounter获取系统时钟无关的时间测量,因此我认为时钟漂移可能不太可能是答案。
这种行为对我没有实际问题,但我希望更好地理解它。它似乎以大约计时器滴答的分辨率运行。Microsoft是否发布了关于此函数精度的进一步详细信息?我应该期望在Vista中有更高的精度吗?

我想建议一个小测试:只需在等待函数之前加上sleep(0)。这很可能会改变行为以满足您的期望。此外:通过使用由QueryPerformanceFrequency()返回的频率将QueryPerformanceCounter()的结果转换为时间值意味着该频率是精确的。给定的频率被视为常量。但底层硬件具有公差。频率始终具有偏移量,甚至可能存在热漂移。 - Arno
1个回答

10

是的,WaitForSingleObject使用计时器滴答分辨率而不是像QueryPerformanceCounter一样使用高分辨率计时器。

http://msdn.microsoft.com/en-us/library/ms687069(VS.85).aspx,“等待函数”MSDN文章对此进行了扩展:

指定的超时时间间隔的准确性取决于系统时钟的分辨率。系统时钟以恒定的速率“滴答”。如果超时间隔小于系统时钟的分辨率,则等待可能在少于指定时长的时间内超时。如果超时间隔大于一个滴答但小于两个滴答,则等待时间可以在一到两个滴答之间,依此类推。

此文章还解释了如何使用timeBeginPeriod来增加系统时钟分辨率-但不建议这样做。

我可以想到几个原因。首先,几乎所有WaitForSingleObject的用例都不需要更高的分辨率。使用高分辨率计时器将需要内核不停地轮询计时器(不可行,因为内核代码不能保证始终运行)或频繁重新编程它以生成中断(因为可能有多个WaitForSingleObjects,而且最可能只有一个可编程中断)。

另一方面,已经存在一个定时源,它以比WaitForSingleObject、SetWaitableTimer和Sleep更好的分辨率不断更新。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接