線程同步之Win32API的Wait函數

線程同步之Win32API的Wait函數

Win32API中的Wait函數非常重要,很多同步都需要Wait函數的配合,Wait函數很多,常用的我就不贅述了,只對一些有用但不常用的函數做一些描述。

1.WaitForSingleObject

最常用的函數,不用多說了。對於信號燈和信號量,每用一次,信號量減一。

DWORD WaitForSingleObject(
  HANDLE hHandle,        // handle to object
  DWORD dwMilliseconds   // time-out interval
);
2.WaitForSingleObjectEx
DWORD WaitForSingleObjectEx(
  HANDLE hHandle,        // handle to object
  DWORD dwMilliseconds,  // time-out interval
  BOOL bAlertable        // alertable option
);
基本上和WaitForSingleObject一致,所不同的在於WaitForSingleObjectEx = 
WaitForSingleObject(,,FALSE),也就是說在參數爲TRUE的情況下可以進入線程告警狀態,
可以使用APC機制。
3.WaitForMultipleObjects
DWORD WaitForMultipleObjects(
  DWORD nCount,             // number of handles in array
  CONST HANDLE *lpHandles,  // object-handle array
  BOOL fWaitAll,            // wait option
  DWORD dwMilliseconds      // time-out interval
);
和WaitForSingleObject不同之處,在於等待多個句柄,這應該是一個與的關係,即是所有的句柄
都需要處於發信號的狀態。
4.WaitForMultipleObjectsEx
DWORD WaitForMultipleObjectsEx(
  DWORD nCount,             // number of handles in array
  CONST HANDLE *lpHandles,  // object-handle array
  BOOL fWaitAll,            // wait option
  DWORD dwMilliseconds,     // time-out interval
  BOOL bAlertable           // alertable option
);
這個不需要多說什麼了。
Note:現在介紹幾種返回值
WAIT_OBJECT_0:狀態處於發信號的狀態。最合理的結束方式。
WAIT_TIMEOUT:超時退出。
WAIT_ABANDONED:針對Mutex對象,就是在owner線程退出之前也沒有釋放Mutex。
WAIT_FAILED:出錯退出。需要使用GetLastErr.
下面的可以能有繞:
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1):
如果fWaitAll是TRUE,返回WAIT_OBJECT_0表示所有句柄都發了信號;
如果fWaitAll是FLASE,返回什麼就是第幾個句柄發了信號。
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1):
如果fWaitAll是TRUE,返回值WAIT_ABANDONED_0表示所有的線程發信號,至少一個線程退出;
如果fWaitAll是TRUE,至少一個線程退出,句柄就是返回值指的那個。
接着我們來看下面兩個函數,一起說了:
DWORD MsgWaitForMultipleObjects(
  DWORD nCount,          // number of handles in array
  CONST HANDLE pHandles, // object-handle array
  BOOL fWaitAll,         // wait option
  DWORD dwMilliseconds,  // time-out interval
  DWORD dwWakeMask       // input-event type
);
DWORD MsgWaitForMultipleObjectsEx(
  DWORD nCount,          // number of handles in array
  CONST HANDLE pHandles, // object-handle array
  DWORD dwMilliseconds,  // time-out interval
  DWORD dwWakeMask,      // input-event type
  DWORD dwFlags          // wait options
);
我感覺這和WaitForMultipleObjects最大的區別在於,前者可以繼續轉消息泵,
而後者能把消息泵都停掉了,所以肯定收不到消息了。
特別提醒,fWaitAll,只能設置成FALSE,謹慎啊。
DWORD SignalObjectAndWait(
  HANDLE hObjectToSignal,  // handle to object to signal
  HANDLE hObjectToWaitOn,  // handle to object to watch
  DWORD dwMilliseconds,    // time-out interval
  BOOL bAlertable          // alertable option
);
向一個句柄發一個信號,接着等待另一個句柄,用起來很簡單,應該可用性很強。
最後說四個函數
BOOL RegisterWaitForSingleObject( 
  PHANDLE phNewWaitObject,       // wait handle
  HANDLE hObject,                // handle to object
  WAITORTIMERCALLBACK Callback,  // timer callback function
  PVOID Context                  // callback function parameter
  ULONG dwMilliseconds,          // time-out interval
  ULONG dwFlags                  // options
); 
這個函數測試了很久,才稍微有點一點心得。首先,Event一定要設定成自動的,
我因爲這個問題吃盡苦頭,然後可以當一個線程池來用,但是還有一個問題,
如下:
BOOL UnregisterWait(
  HANDLE WaitHandle      // wait handle
);
BOOL UnregisterWaitEx(
  HANDLE WaitHandle,      // wait handle
  HANDLE CompletionEvent  // completion event
);
這個函數在使用的時候需要保護句柄,呵呵,否則系統很生氣,後果很嚴重:)
建議使用INVALID_HANDLE_VALUE作爲第二個參數,它會等到任務結束後,才註銷。
VOID CALLBACK WaitOrTimerCallback(
  PVOID lpParameter,        // thread data
  BOOLEAN TimerOrWaitFired  // reason
);
回調函數無需贅述。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章