標籤:tee 執行個體 eset 安全 接下來 參數 AC lpcwstr multi
前面說的互斥量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.參數說明
(四)、 將事件設為末觸發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;}
運行結果如下所示:
windows多線程(七) 事件event