2009-05-21 142 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來說已經足夠了。