WaitForSingleObject的作用[轉]


總結: 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM