C++ 事件(event)使用总结

  事件最常用在多线程同步互斥机制。

 常用的函数有:

 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;
}

执行结果如下图:

AI浩 CSDN认证博客专家 Pytorch C# C++
我就是对AI感兴趣,希望和大家一起交流学习AI,如果我的文章有错误,欢迎大家指正!
相关推荐
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页