WaitForSingleObject


  在多線程的情況下,有時候我們會希望等待某一線程完成了再繼續做其他事情,要實現這個目的,可以使用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 表示對象有信號,但還是不能執行  一般是因為未獲取到鎖或其他原因

代碼例如下:

// ConsoleApplication1.cpp : 定義控制台應用程序的入口點。
//
 
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include <iostream>
using namespace std;
 
int i = 0;
DWORD WINAPI FunProc(LPVOID lpParameter);
 
DWORD WINAPI FunProc(LPVOID lpParameter)
{
	for (; i < 10; i++)
	{
		if (!(i % 10))
			cout << endl;
		else
			cout << i << endl;
	}
	return 0;
}
 
void main()
{
	cout << i << endl;
	HANDLE hThread;
	hThread = CreateThread(NULL, 0, FunProc, NULL, 0, NULL);
	DWORD dwRet = WaitForSingleObject(hThread, 1);
	if (dwRet == WAIT_OBJECT_0)
	{
		cout<< "創建的線程執行結束" << endl;
	}
	if (dwRet == WAIT_TIMEOUT)
	{
		cout<< "等待超時" << endl;
	}
	if (dwRet == WAIT_ABANDONED)
	{
		cout<< "Abandoned" << endl;
	}
	CloseHandle(hThread);
	system("pause");
}
 

  

 

這段代碼中,首先在開始定義一個變量  i  為  0 ,然后在主函數中先將其輸出便有了結果中第一行的  0 。

之后我們開啟線程,進入線程函數FunProc,在FunProc中將  i++ 對 10 取余輸出,一直到 i > 10 結束循環,線程結束,這是返回給WaitForSingleObject的結果為WAIT_OBJECT_0,表示線程正常結束,並將結果輸出。

這其中WaitForSingleObject的效果就相當於一個關卡,只有返回給了WaitForSingleObject結果程序才能繼續執行,當然線程不一定能正常執行結束,也可能會出現:

這就是未能等到線程結束信號量的等待時間就耗光了。我們也可以將WaitForSingleObject的第二個參數設置為 INFINITE,就可以一直等待。

 


免責聲明!

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



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