總結: WaitForSingleObject( HANDLE hHandle, DWORDdwMilliseconds)是主線程等待hHandle對應的線程.
在多線程的情況下,有時候我們會希望等待某一線程完成了再繼續做其他事情(比如主線程等待子線程結束完之后,自己再結束),要實現這個目的,可以使用Windows API函數WaitForSingleObject,或者WaitForMultipleObjects。這兩個函數都會等待Object被標為有信號(signaled)時才返回的。
那么,信號是什么呢?首先我們可以假設這里存在一個文件和兩個線程,我們規定這個文件同一時刻只能被一個線程所訪問打開,那么我們的線程該如何知道這個文件現在有沒有被別的線程訪問呢?我們可以讓線程等在一個死循環里,這個循環之一在嘗試打開訪問這個文件,直到能夠打開為止;這樣做雖然可以實現目的,但是死循環會占用大量的內存,所以windows就設置了信號量。信號量的作用簡單理解就是一個標志位,在我們上述的問題中,這個文件就有一個信號量,初始時我們設信號量為FALSE,而只有當信號量為FALSE時線程才可以打開訪問這個文件。那么,當第一個線程到達,信號量為FALSE,線程打開文件進行訪問,並將信號量置為TRUE;在第一個線程在訪問文件時,第二個線程到來,此時信號量仍未TRUE,所以第二個線程等待,這個等待的過程就是WaitForSingleObject。WaitForSingleObject在等待的過程中會進入一個非常高效的沉睡等待狀態,只占用極少的CPU時間片。
WaitForSingleObject()
1. 格式
DWORD WaitForSingleObject( HANDLE hHandle, DWORDdwMilliseconds);
有兩個參數,分別是THandle和Timeout(毫秒單位)。
如果想要等待一條線程,那么你需要指定線程的Handle,以及相應的Timeout時間。當然,如果你想無限等待下去,Timeout參數可以指定系統常量INFINITE。
2. 使用對象
它可以等待如下幾種類型的對象:
Event,Mutex,Semaphore,Process,Thread
3. 返回類型
有三種返回類型:
WAIT_OBJECT_0, 表示等待的對象有信號(對線程來說,表示執行結束);
WAIT_TIMEOUT, 表示等待指定時間內,對象一直沒有信號(線程沒執行完);
WAIT_ABANDONED 表示對象有信號,但還是不能執行 一般是因為未獲取到鎖或其他原因
代碼例如下:
1 // ConsoleApplication1.cpp : 定義控制台應用程序的入口點。 2 // 3 4 #include "stdafx.h" 5 #include "stdio.h" 6 #include "windows.h" 7 #include <iostream> 8 using namespace std; 9 10 int i = 0; 11 DWORD WINAPI FunProc(LPVOID lpParameter); 12 13 DWORD WINAPI FunProc(LPVOID lpParameter) 14 { 15 for (; i < 10; i++) 16 { 17 if (!(i % 10)) 18 cout << endl; 19 else 20 cout << i << endl; 21 } 22 return 0; 23 } 24 25 void main() 26 { 27 cout << i << endl; 28 HANDLE hThread; 29 hThread = CreateThread(NULL, 0, FunProc, NULL, 0, NULL); 30 DWORD dwRet = WaitForSingleObject(hThread, 1); 31 if (dwRet == WAIT_OBJECT_0) 32 { 33 cout<< "創建的線程執行結束" << endl; 34 } 35 if (dwRet == WAIT_TIMEOUT) 36 { 37 cout<< "等待超時" << endl; 38 } 39 if (dwRet == WAIT_ABANDONED) 40 { 41 cout<< "Abandoned" << endl; 42 } 43 CloseHandle(hThread); 44 system("pause"); 45 } 46
結果為:
這段代碼中,首先在開始定義一個變量 i 為 0 ,然后在主函數中先將其輸出便有了結果中第一行的 0 。
之后我們開啟線程,進入線程函數FunProc,在FunProc中將 i++ 對 10 取余輸出,一直到 i > 10 結束循環,線程結束,這是返回給WaitForSingleObject的結果為WAIT_OBJECT_0,表示線程正常結束,並將結果輸出。
這其中WaitForSingleObject的效果就相當於一個關卡,只有返回給了WaitForSingleObject結果程序才能繼續執行,當然線程不一定能正常執行結束,也可能會出現:
這就是未能等到線程結束信號量的等待時間就耗光了。我們也可以將WaitForSingleObject的第二個參數設置為 INFINITE,就可以一直等待。
線程所等待的對象變為有信號狀態,則該函數立即返回;如果超時時間已經到達dwMilliseconds毫秒,但hHandle所指向的對象還沒有變成有信號狀態,函數照樣返回(那區別在哪呢? 一個是有信號的主動返回,另一個是沒信號的超時被動返回)
————————————————
版權聲明:本文為CSDN博主「LL596214569」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/LL596214569/article/details/81088862
這個帖子里講了使用超時時間的作用:
解決方案:
要解決等待並刷新,可以
重復
ret:= WaitforSingleObject(ProcessInfo.hProcess ,100); //等待
Application.ProcessMessages;
直到ret&lt; Wait_Timeout;
即每次只等待很短的時間,然后刷新界面,如果程序沒有運行完成,則繼續等待,否則
跳出。
另一篇文章,里面講到了一個比較有用的功能:也講了獲取進程的一些方法
WaitForSingleObject的用法-(判斷一個程序是否結束)
https://blog.csdn.net/iteye_3224/article/details/82123379