События чаще всего используются в механизмах многопоточной синхронизации и взаимного исключения.
Часто используемые функции:
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;
}
Результат выполнения следующий: