CreateWaitableTimer與SetWaitableTimer詳解

來源:互聯網
上載者:User

可等待定時器問題:

1. 需要的函數:CreateWaitableTimer,SetWaitableTimer.前者建立一個可等待定時器控制代碼,後者設定等待定時器觸發的條件.我們可以多次調用SetWaitableTimer來重設可等待定時器.重設後之前的定時器將關閉.

2. 主要看兩段代碼:

代碼一:(這段代碼在網上出現的機率是較大的)

[cpp] view plaincopyprint?
  1. HANDLE hTimer = CreateWaitableTimer( NULL,FALSE,NULL ); 
  2.  
  3. LARGE_INTEGER li; 
  4.  
  5. li.QuadPart = 0; 
  6.  
  7.  
  8. if( !SetWaitableTimer( hTimer,&li,1000,NULL,NULL,FALSE )) 
  9.  
  10.  
  11. CloseHandle( hTimer ); 
  12.  
  13. return; 
  14.  
  15.  
  16. while ( 1 ) 
  17.  
  18.  
  19. //clock_t c_beg = clock();  
  20.  
  21. WaitForSingleObject( hTimer,INFINITE ); 
  22.  
  23. //clock_t end = clock() - c_beg;  
  24.  
  25. //cout<<"time:"<<end<<endl;  
  26.  
  27. cout<<"定時器觸發了...\n"; 
  28.  
  29.  
  30. CloseHandle(hTimer); 
HANDLE hTimer = CreateWaitableTimer( NULL,FALSE,NULL );LARGE_INTEGER li;li.QuadPart = 0;if( !SetWaitableTimer( hTimer,&li,1000,NULL,NULL,FALSE )){CloseHandle( hTimer );return;}while ( 1 ){//clock_t c_beg = clock();WaitForSingleObject( hTimer,INFINITE );//clock_t end = clock() - c_beg;//cout<<"time:"<<end<<endl;cout<<"定時器觸發了...\n";}CloseHandle(hTimer);

 

 

通過將上面注釋的代碼放開,我們可以發現:

◆ 前兩個定時器出發過程”不穩定”(即它們所耗費的時間並不是1秒.

◆ 就算是穩定了以後,定時器的差距並不是1s而是1000(毫秒)左右,這就奇怪了.

如果說第二個問題是由於執行clock而產生的誤差的話,那麼第一個問題則沒辦法解釋.(其實對於clock的時間幾乎是可以忽略不計的.)

這樣就引入了核心編程裡面作者的代碼:

代碼二:

[cpp] view plaincopyprint?
  1. HANDLE hTimer = CreateWaitableTimer( NULL,FALSE,NULL ); 
  2.  
  3. LARGE_INTEGER li; 
  4.  
  5. li.QuadPart = 0; 
  6.  
  7.  
  8. if( !SetWaitableTimer( hTimer,&li,1000,NULL,NULL,FALSE )) 
  9.  
  10.  
  11. CloseHandle( hTimer ); 
  12.  
  13. return; 
  14.  
  15.  
  16.  
  17. while ( 1 ) 
  18.  
  19.  
  20. clock_t c_beg = clock(); 
  21.  
  22. SleepEx( 1000,TRUE );//這裡並沒有使用WaitForSingleObject,而是使用SleepEx  
  23.  
  24. clock_t end = clock() - c_beg; 
  25.  
  26. cout<<"time:"<<end<<endl; 
  27.  
  28.  
  29. CloseHandle(hTimer); 
HANDLE hTimer = CreateWaitableTimer( NULL,FALSE,NULL );LARGE_INTEGER li;li.QuadPart = 0;if( !SetWaitableTimer( hTimer,&li,1000,NULL,NULL,FALSE )){CloseHandle( hTimer );return;}while ( 1 ){clock_t c_beg = clock();SleepEx( 1000,TRUE );//這裡並沒有使用WaitForSingleObject,而是使用SleepExclock_t end = clock() - c_beg;cout<<"time:"<<end<<endl;}CloseHandle(hTimer);

 

運行結果發現正常:每次都是1000(毫秒).

從這裡可以間接證明,clock消耗的時間可以忽略不計.

再來看看SleepEx是怎麼定義的.

DWORD WINAPI SleepEx(

    DWORD dwMillesconds,

    BOOL bAlertable);

這裡主要說明第二個參數的用途:線程是否將自己置為可提醒狀態.(在可提醒I/O中,當I/O完成時,系統將他們添加到線程APC隊列中-回呼函數不會立即被調用.如果我們想讓其被調用需要將這個參數設定為TRUE).

本例並沒有牽涉到這類問題,所以無論FALSE或者TRUE都無所謂.

如果我們只想要定義一個一次性定時器.可以參考如下代碼:

[cpp] view plaincopyprint?
  1. HANDLE hTimer = NULL; 
  2.  
  3. LARGE_INTEGER liDueTime; 
  4.  
  5.   liDueTime.QuadPart = -100000000;//10s  
  6.  
  7. hTimer = CreateWaitableTimer(NULL, TRUE,NULL); 
  8.  
  9.     if ( hTimer == NULL ) return; 
  10.  
  11.     if (!SetWaitableTimer(hTimer, &liDueTime, 1000, NULL, NULL, 0)) 
  12.  
  13.     {  
  14.  
  15. CloseHandle(hTimer); 
  16.  
  17.         return; 
  18.  
  19.  
  20. clock_t c_beg = clock(); 
  21.  
  22. if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) 
  23.  
  24.  
  25. CloseHandle(hTimer); 
  26.  
  27. return ; 
  28.  
  29.  
  30. else 
  31.  
  32.  
  33. //操作  
  34.  
  35.  
  36. CloseHandle(hTimer); 
HANDLE hTimer = NULL;LARGE_INTEGER liDueTime;  liDueTime.QuadPart = -100000000;//10shTimer = CreateWaitableTimer(NULL, TRUE,NULL);    if ( hTimer == NULL ) return;    if (!SetWaitableTimer(hTimer, &liDueTime, 1000, NULL, NULL, 0))    { CloseHandle(hTimer);        return;}clock_t c_beg = clock();if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0){CloseHandle(hTimer);return ;}else{//操作}CloseHandle(hTimer);

最後需要說明的一點是APC(非同步呼叫過程)加入定時器中:

[cpp] view plaincopyprint?
  1. VOID APIENTRY TimerAPCRoutine( PVOID pvArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue) 
  2.  
  3.  
  4. cout<<"high:"<<dwTimerHighValue<<"      low"<<dwTimerLowValue<<endl; 
  5.  
  6.  
  7. void main() 
  8.  
  9.  
  10. HANDLE hTimer = CreateWaitableTimer( NULL,FALSE,NULL ); 
  11.  
  12. LARGE_INTEGER li; 
  13.  
  14. li.QuadPart = 0; 
  15.  
  16.  
  17. if( !SetWaitableTimer( hTimer,&li,1000,TimerAPCRoutine,NULL,FALSE )) 
  18.  
  19.  
  20. CloseHandle( hTimer ); 
  21.  
  22. return; 
  23.  
  24.  
  25.  
  26. while ( 1 ) 
  27.  
  28.  
  29. SleepEx( 1000,TRUE ); 
  30.  
  31.  
  32. CloseHandle( hTimer ); 
  33.  
  34. getchar(); 
  35.  
VOID APIENTRY TimerAPCRoutine( PVOID pvArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue){cout<<"high:"<<dwTimerHighValue<<"      low"<<dwTimerLowValue<<endl;}void main(){HANDLE hTimer = CreateWaitableTimer( NULL,FALSE,NULL );LARGE_INTEGER li;li.QuadPart = 0;if( !SetWaitableTimer( hTimer,&li,1000,TimerAPCRoutine,NULL,FALSE )){CloseHandle( hTimer );return;}while ( 1 ){SleepEx( 1000,TRUE );}CloseHandle( hTimer );getchar();}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.