2014-01-27 45 views
2

我面對一個奇怪的行爲,等待定時器。如果我用一秒鐘的時間創建它,然後在第一次觸發後,其後續觸發似乎與幾毫秒的值「對齊」,這與第一次觸發明顯不同。奇怪的等待定時器「對齊」問題

這裏是舉例火時間(小時:分鐘:seconds.milliseconds):

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的

任何人都知道爲什麼出現這種情況?我可以想象,可以通過一些系統優化來減少定時器中斷和/或上下文切換。但我無法在任何地方找到它。這是意想不到的,並可能導致問題。

回答

2
dueTime.QuadPart = 0; 

您打算如何使用此聲明?

的文件說:「正值表示絕對時間」和「負值表示相對時間」。零從未爲dueTime指定可能的值。

相反,你768,16通過指定

  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個納秒單位適當的時候。這並不意味着他們可以以這種精確度觸發。準確度由系統時間粒度決定。有關係統時間粒度的更多詳細信息,請參閱this答案。

+0

我以爲零值意味着第一個計時器事件立即被觸發(如在其他計時器功能的情況下)。除了SetWaitableTimer返回TRUE,所以我從來沒有想過零是無效值。 MSDN不明確指定零是不允許的,除了我描述的問題,它的行爲是正確的。但改變其他價值的時間「固定」了這個問題。謝謝。 – jesse