windows多線程(七) 事件event


前面說的互斥量Mutex與關鍵段CriticalSection都不能實現線程的同步,只能實現互斥,接下來我們用時間event就可以實現線程的同步了,事件也是一個內核對象。

一、相關函數說明

(一) 創建事件
1.函數原型

HANDLE WINAPI CreateEventW(
			    _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
			    _In_ BOOL bManualReset,
			    _In_ BOOL bInitialState,
			    _In_opt_ LPCWSTR lpName
			    );


2.參數說明
  • 第一個參數表示安全控制,一般直接傳入NULL。

  • 第二個參數確定事件是手動置位還是自動置位,傳入TRUE表示手動置位,傳入FALSE表示自動置位。如果為自動置位,則對該事件調用WaitForSingleObject()后會自動調用ResetEvent()使事件變成未觸發狀態。

  • 第三個參數表示事件的初始狀態,傳入TRUR表示已觸發。

  • 第四個參數表示事件的名稱,傳入NULL表示匿名事件。

(二) 打開事件
1.函數原型

HANDLE WINAPI OpenEventW(
			    _In_ DWORD  dwDesiredAccess,
			    _In_ BOOL  bInheritHandle,
			    _In_ LPCWSTR  lpName
			    );


2.參數說明
  • 第一個參數表示訪問權限,對事件一般傳入EVENT_ALL_ACCESS。

  • 第二個參數表示事件句柄繼承性,一般傳入TRUE即可。

  • 第三個參數表示名稱,不同進程中的各線程可以通過名稱來確保它們訪問同一個事件。

(三) 觸發事件
1.函數原型

BOOL WINAPI SetEvent(
			  _In_ HANDLE hEvent
			);

2.參數說明
  • 函數說明:每次觸發后,必有一個或多個處於等待狀態下的線程變成可調度狀態。

  • hEvent 為要觸發的事件的句柄(內核對象)

(四)、 將事件設為末觸發
1.函數原型

BOOL WINAPI ResetEvent(
			  _In_ HANDLE hEvent
			);


2.參數說明
  • hEvent 為要觸發的事件的句柄(內核對象)

二、實例

前面我們用關鍵段和互斥量無法實現線程同步,在前面的程序中,我們可以實現對全局資源互斥訪問,即每個線程給全局資源加一,現在使用事件可以時間線程同步,即實現每個線程按順序依次給全局資源加一,代碼如下:



//使用事件進行線程同步

#include<iostream>
#include <windows.h>

using namespace std;

CRITICAL_SECTION g_csVar;
HANDLE g_event;
const int THREAD_NUM = 10;
int g_Num = 0;

DWORD WINAPI  Func(LPVOID);


int main()
{
	g_event = CreateEvent(NULL, false, false, NULL);	//初始化事件為未觸發狀態
	InitializeCriticalSection(&g_csVar);
	DWORD  ThreadId[THREAD_NUM];
	HANDLE handle[THREAD_NUM];
	int i = 0;
	while (i < THREAD_NUM)
	{
		handle[i] = CreateThread(NULL, 0, Func, &i, 0, &ThreadId[i]);
		WaitForSingleObject(g_event, INFINITE);	//等待事件被觸發
		i++;
	}
	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);

	CloseHandle(g_event);
	DeleteCriticalSection(&g_csVar);
	return 0;
}


DWORD WINAPI Func(LPVOID p)
{
	int nThreadNum = *(int*)p;
	
	EnterCriticalSection(&g_csVar);
	cout << "線程編號為:" << nThreadNum << " 給全局資源g_Num 加1,現在給全局資源g_Num值為:" << ++g_Num << endl;
	LeaveCriticalSection(&g_csVar);
	SetEvent(g_event);	//觸發事件
	return 0;
}

運行結果如下所示:


免責聲明!

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



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