2009-05-21 141 views
11

当我使用WaitForSingleObject函数等待非信号事件时,我发现在某些情况下,调用将返回小于指定的超时期限的WAIT_TIMEOUT。简单地循环呼叫的超时设置为1000ms,我已经看到呼叫在低至990ms的时间内(在WinXP上运行)返回。我使用QueryPerformanceCounter来获得系统时钟无关的时间测量,所以我不认为时钟漂移可能是一个答案。WaitForSingleObject的超时分辨率

此行为对我来说不存在任何实际问题,但我想更好地理解它。看起来它可能在大约计时器分辨率的分辨率下工作。微软是否发布关于此功能精度的更多细节?我应该期待Vista的更高精度吗?

+0

我想推荐一个小测试:在等待函数前面加一个`sleep(0)`。这很可能会改变行为以满足您的期望。另外:通过使用由QueryPerformanceFrequency()返回的频率将QueryPerformanceCounter()的结果转换为时间值意味着频率是精确的。给定的频率被视为一个常数。但unterlaying硬件有容差。频率始终有一个偏移量,甚至可能存在热漂移。 – Arno 2012-08-02 13:06:22

回答

8

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

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

指定超时 间隔的准确性取决于 系统时钟的分辨率。系统时钟 以固定速率“滴答”。如果 超时间隔小于系统时钟的分辨率 ,则等待时间可能会超过指定的时间长度。如果 超时间隔大于一个 打勾但小于两个,则等待可能为 为1-2个刻度之间的任意值, 等等。

本文还解释了如何使用timeBeginPeriod提高系统时钟分辨率 - 但不建议这样做。

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

另一方面,已经有一个定时源不断更新,其分辨率对WaitForSingleObject,SetWaitableTimer和Sleep来说已经足够了。