Event是內核對象,他可以分為自動和手動兩種模式。
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
參數
lpEventAttributes 安全屬性。NULL 表示使用默認屬性。該屬性在
Windows 95中會被忽略。
bManualReset 如為FALSE,表示這個event 將在變成激發狀態
(因而喚醒一個線程)之后,自動重置(reset)為
非激發狀態。如果是TRUE,表示不會自動重置,
必須靠程序操作(調用ResetEvent())才能將激發
狀態的event 重置為非激發狀態。
bInitialState 如為TRUE,表示這個event 一開始處於激發狀
態。如為FALSE,則表示這個event 一開始處於
非激發狀態。
lpNameEvent 對象的名稱。任何線程或進程都可以根據這
個文字名稱,使用這一event 對象。
SetEvent() 把event 對象設為激發狀態 ResetEvent() 把event 對象設為非激發狀態(譯注:在此我要提醒讀者, "Reset" 的意思是“設定為非激發狀態”,而非“重新設定為 激發狀態”。) PulseEvent() 如果是一個 Manual Reset Event :把event 對象設為激發狀 態,喚醒“所有”等待中的線程,然后event 恢復為非激發 狀態。如果是一個Auto Reset Event:把event 對象設為激 發狀態,喚醒“一個”等待中的線程,然后event 恢復為非 激發狀態
下面做一個模擬實驗,用兩個線程輪流輸出10次,當然哪個先開始也是可以控制的。
#pragma once #include <Windows.h> #include <iostream> using namespace std; class EventOption { public: EventOption(void); ~EventOption(void); void StartRnner(); void ReleaseOption(); private: static DWORD WINAPI ThreadFunctionA(LPVOID param); static DWORD WINAPI ThreadFunctionB(LPVOID param); void FunctionA(); void FunctionB(); private: HANDLE m_hThreadA; HANDLE m_hThreadB; HANDLE m_hEventA; HANDLE m_hEventB; }; #include "EventOption.h" EventOption::EventOption(void) { } EventOption::~EventOption(void) { } // interface void EventOption::StartRnner() { m_hEventA = CreateEvent(NULL, TRUE, FALSE, NULL); m_hEventB = CreateEvent(NULL, TRUE, FALSE, NULL); SetEvent(m_hEventA); m_hThreadA = CreateThread(NULL, 0, ThreadFunctionA, this, 0, NULL); m_hThreadB = CreateThread(NULL, 0, ThreadFunctionB, this, 0, NULL); } void EventOption::ReleaseOption() { WaitForSingleObject(m_hThreadA, INFINITE); WaitForSingleObject(m_hThreadB, INFINITE); CloseHandle(m_hEventA); CloseHandle(m_hEventB); CloseHandle(m_hThreadA); CloseHandle(m_hThreadB); } //private DWORD EventOption::ThreadFunctionA(LPVOID param) { EventOption *pThis = (EventOption*)param; pThis->FunctionA(); return 0; } DWORD EventOption::ThreadFunctionB(LPVOID param) { EventOption *pThis = (EventOption*)param; pThis->FunctionB(); return 0; } void EventOption::FunctionA() { int iCount = 10; while(iCount--) { WaitForSingleObject(m_hEventA, INFINITE); cout<<"FunctionA: "<<iCount<<endl; ResetEvent(m_hEventA); SetEvent(m_hEventB); } } void EventOption::FunctionB() { int iCount = 10; while(iCount--) { WaitForSingleObject(m_hEventB, INFINITE); cout<<"FunctionB: "<<iCount<<endl; ResetEvent(m_hEventB); SetEvent(m_hEventA); } } #include "EventOption.h" int _tmain(int argc, _TCHAR* argv[]) { EventOption test; test.StartRnner(); test.ReleaseOption(); ::getchar(); return 0; }
