在多線程下面,有時候會希望等待某一線程完成了再繼續做其他事情,要實現這個目的,可以使用Windows API函數WaitForSingleObject,或者WaitForMultipleObjects。這兩個函數都會等待Object被標為有信號(signaled)時才返回的。
那么,什么是信號呢?簡單來說,Windows下創建的Object都會被賦予一個狀態量。如果Object被激活了,或者正在使用,那么該Object就是無信號,也就是不可用;另一方面,如果Object可用了,那么它就恢復有信號了。這兩個函數的優點是它們在等待的過程中會進入一個非常高效沉睡狀態,只占用極少的CPU時間片。(這兩個函數都是在內核狀態下等待內核對象,不切換到用戶模式下,因而效率很高)
WaitForSingleObject函數來等待一個內核對象變為已通知狀態:
DWORD WaitForSingleObject( HANDLE hObject, //指明一個內核對象的句柄 DWORD dwMilliseconds); //等待時間
該函數需要傳遞一個內核對象句柄,該句柄標識一個內核對象,
如果該內核對象處於未通知狀態,則該函數導致線程進入阻塞狀態;
如果該內核對象處於已通知狀態,則該函數立即返回WAIT_OBJECT_0。
第二個參數指明了需要等待的時間(毫秒),可以傳遞INFINITE指明要無限期等待下去,
如果第二個參數為0,那么函數就測試同步對象的狀態並立即返回。
如果等待超時,該函數返回WAIT_TIMEOUT。
如果該函數失敗,返回WAIT_FAILED。可以通過下面的代碼來判斷
- LPVOID lpMsgBuf;
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
- MessageBox( (LPCTSTR)lpMsgBuf);
- LocalFree( lpMsgBuf );
--------------------------------------------WaitForMultipleObjects()-------------------------------------------
- <span style="font-size:18px;">WaitForMultipleObjects()允許你在同一時間等待一個以上的對象。
- DWORD WaitForMultipleObject(
- DWORD nCount, //表示lphandles數組的元素個數
- CONST HANDLE *lphandles, //指向一個有對象handles組成的數組。
- BOOL bWaitAll, //如果為true,則表示所有的handles都必須激發,此函數才得以返回,否則,此函數將在任何一個handle激發時就返回。
- DWORD dwMilliseconds //超時也返回,可為0,立即返回,INFINITE表示無窮等待。
- );</span>
返回值:
如果因時間終了而返回,則返回值是WAIT_TIMEOUT,類似WaitForSingleObject().
如果bWaitAll是TRUE,則返回值將是WAIT_OBJECT_0.
如果bWaitAll是FALSE,那么將返回值減去WAIT_OBJECT_0,就表示數組中的哪一個handle被激發了。
如果你等待的對象中有任何mutexes,那么返回值可能從WAIT_ABANDONED_0到WAIT_ABANDONED_0+nCount-1.
如果函數失敗,則返回WAIT_FAILED。可以使用GetLastError找出失敗原因。
WaitForSingleObject測試方法:
- DWORD dw = WaitForSingleObject(hProcess, 5000); //等待一個進程結束
- switch (dw)
- {
- case WAIT_OBJECT_0:
- // hProcess所代表的進程在5秒內結束
- break;
- case WAIT_TIMEOUT:
- // 等待時間超過5秒
- break;
- case WAIT_FAILED:
- // 函數調用失敗,比如傳遞了一個無效的句柄
- break;
- }
WaitForSingleObject測試方法:
WaitForMulitpleObjects函數來等待多個內核對象變為已通知狀態:
- DWORD WaitForMultipleObjects(
- DWORD dwCount, //等待的內核對象個數
- CONST HANDLE* phObjects, //一個存放被等待的內核對象句柄的數組
- BOOL bWaitAll, //是否等到所有內核對象為已通知狀態后才返回
- DWORD dwMilliseconds); //等待時間
該函數的第一個參數指明等待的內核對象的個數,可以是0到MAXIMUM_WAIT_OBJECTS(64)中的一個值。phObjects參數是一個存放等待的內核對象句柄的數組。bWaitAll參數如果為TRUE,則只有當等待的所有內核對象為已通知狀態時函數才返回,如果為FALSE,則只要一個內核對象為已通知狀態,則該函數返回。第四個參數和WaitForSingleObject中的dwMilliseconds參數類似。
該函數失敗,返回WAIT_FAILED;如果超時,返回WAIT_TIMEOUT;如果bWaitAll參數為TRUE,函數成功則返回WAIT_OBJECT_0,如果bWaitAll為FALSE,函數成功則返回值指明是哪個內核對象收到通知。
可以如下使用該函數:
- HANDLE h[3]; //句柄數組
- //三個進程句柄
- h[0] = hProcess1;
- h[1] = hProcess2;
- h[2] = hProcess3;
- DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000); //等待3個進程結束
- switch (dw)
- {
- case WAIT_FAILED:
- // 函數呼叫失敗
- break;
- case WAIT_TIMEOUT:
- // 超時
- break;
- case WAIT_OBJECT_0 + 0:
- // h[0](hProcess1)所代表的進程結束
- break;
- case WAIT_OBJECT_0 + 1:
- // h[1](hProcess2)所代表的進程結束
- break;
- case WAIT_OBJECT_0 + 2:
- // h[2](hProcess3)所代表的進程結束
- break;
- }
附:測試代碼下載地址 :http://download.csdn.net/detail/makenothing/9497235

http://blog.csdn.net/makenothing/article/details/51197726