事件最常用在多线程同步互斥机制。
常用的函数有:
1、CreateEvent 创建事件。
函数原型如下所示,一共四个参数:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构指针,可为NULL
BOOL bManualReset, // 手动/自动
// TRUE:表示手动,在WaitForSingleObject后必须手动调用ResetEvent清除信号
// FALSE:表示自动,在WaitForSingleObject后,系统自动清除事件信号
BOOL bInitialState, //初始状态,FALSE为无信号,TRUE为有信号
LPCTSTR lpName //事件的名称
);
2、SetEvent:设置为激活触发状态。
3、ResetEvent:设置为未激活触发状态。
4、WaitForSingleObject:检测信号,如果未激活,代码就会处于挂起状态,不再往下执行。
下面是多线程同步的示例:
#include <tchar.h> #include <iostream> #include <wtypes.h> using namespace std; DWORD WINAPI ThreadProc(LPVOID lpParam); DWORD WINAPI ThreadProc2(LPVOID lpParam); DWORD g_dwThreadID; DWORD g_dwThreadID2; UINT g_nTickets = 300; HANDLE g_hEvent1 = NULL; HANDLE g_hEvent2 = NULL; CRITICAL_SECTION g_cs; int ThreadCout = 0; int main(int argc, _TCHAR* argv[]) { cout << "Main thread is running." << endl; InitializeCriticalSection(&g_cs);//初始化临界区 HANDLE hHandle = CreateThread(NULL, 0, ThreadProc, NULL, 0, &g_dwThreadID); ThreadCout++; HANDLE hHandle2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, &g_dwThreadID2); ThreadCout++; g_hEvent1 = CreateEvent(NULL, FALSE, TRUE, NULL); //备注5:g_hEvent1 = CreateEvent(NULL, TRUE, TRUE, NULL); g_hEvent2 = CreateEvent(NULL, FALSE, TRUE, NULL); //备注5:g_hEvent2 = CreateEvent(NULL, TRUE, TRUE, NULL); ResetEvent(g_hEvent1); ResetEvent(g_hEvent2); SetEvent(g_hEvent1); while (TRUE) { EnterCriticalSection(&g_cs); int nCount = ThreadCout; LeaveCriticalSection(&g_cs); if (nCount == 0) { cout << "Main break" << endl; break; } } Sleep(1000); //备注4 CloseHandle(hHandle); CloseHandle(hHandle2); DeleteCriticalSection(&g_cs); cout << "Main End " << endl; system("pause"); return 0; } DWORD WINAPI ThreadProc(LPVOID lpParam) { while (TRUE) { WaitForSingleObject(g_hEvent1, INFINITE); cout << "线程1:" << g_dwThreadID << " thread is running." << endl; EnterCriticalSection(&g_cs); int temp = g_nTickets; LeaveCriticalSection(&g_cs); cout << "线程1:" << g_dwThreadID << " thread is temp." << endl; if (temp > 0) { Sleep(100); //Sleep(1000) cout << "线程1:" << g_dwThreadID << " sell ticket : " << temp << endl; EnterCriticalSection(&g_cs); g_nTickets--; LeaveCriticalSection(&g_cs); SetEvent(g_hEvent2); } else { cout << "线程1 break" << endl; SetEvent(g_hEvent2);//没有这个ThreadProc2不能终止 break; } } EnterCriticalSection(&g_cs); ThreadCout--; LeaveCriticalSection(&g_cs); cout << "线程1 end" << endl; return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParam) { while (TRUE) { WaitForSingleObject(g_hEvent2, INFINITE); cout << "线程2: " << g_dwThreadID2 << " thread is running." << endl; EnterCriticalSection(&g_cs); int temp = g_nTickets; LeaveCriticalSection(&g_cs); if (temp > 0) { Sleep(100); //Sleep(1000) //备注2 cout << "线程2:" << g_dwThreadID2 << " sell ticket : " << temp << endl; EnterCriticalSection(&g_cs); g_nTickets--; LeaveCriticalSection(&g_cs); SetEvent(g_hEvent1); } else { cout << "线程2 break" << endl; SetEvent(g_hEvent1);//同样的问题,没有这个ThreadProc不能终止 break; } } EnterCriticalSection(&g_cs); ThreadCout--; LeaveCriticalSection(&g_cs); cout << "线程2 end" << endl; return 0; }
执行结果如下图: