多线程(9)多线程同步之事件对象(windows实现)

1. 事件(对象)的概念:

事件是内核对象,多用于线程间通信,可以跨进程同步,用于一个线程来唤醒另一个线程(包括自动和人工两种方式)。

2.接口函数

2.1 创建事件-CreateEvent

2.1 原型

HANDLE CreateEvent(
	LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性
	BOOLbManualReset,// 复位方式
	BOOLbInitialState,  // initial state初始状态
	LPCTSTRlpName // 对象名称
	);

2.2 说明

调用过程中的任何线程,都可以在一个等待函数中指定事件对象句柄。
当指定的对象的状态为有信号时,单对象等待函数(例如WaitForSingleObject)返回

2.3 参数-bManualReset

一、 bManualReset:
指定将创建的EVENT是自动复位还是手动复位。

  1. 如果为TRUE,需要用 ResetEvent(HANDLE)函数手动复位状态为无信号,即一旦改EVENT被设置成有信号,则它会一直等到ResetEvent调用时才为无信号状态。
  2. 如果为FALSE,当一个有信号的等待线程被释放后,系统会自动复位状态为无信号状态。

二、bInitialState:
指定事件对象的初始状态。
如果为TRUE,初始状态为有信号,否则为无信号。

2.4 举例子:

  1. hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    //线程释放后自动重置为无信号状态,初始化时为无信号状态
    因为初始为无信号状态,所以hEvent一直处于无信号状态,
    因此这线程一直在等待,直到主线程结束。

  2. hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
    使用手动重置为无信号状态,初始化时有信号状态
    所以hEvent一直处于有信号状态,无论是线程1释放后,hEvent仍处于有信号状态,所以线程2正常执行了。

2.1 设置信号状态-SetEvent

SetEvent(hEvent))//设置信号为有信号状态
ResetEvent,这个函数把指定的事件对象设置为无信号状态。

3.代码例子

HANDLE hEvent,hEventOne,hEventTwo;

DWORD WINAPI eventThreadOne(LPVOID lp)
{
	cout<<"-----in eventThread One-----"<<endl;
	DWORD res =WaitForSingleObject(hEvent,INFINITE);
	if (WAIT_OBJECT_0 == res)
	{
		cout<<"eventThread One wait event"<<endl;
	}

	if(!SetEvent(hEvent))//场景2 4 置为有信号 BOOL SetEvent(HANDLE hEvent);
	{
		cout<<"set event fail"<<endl;
	}
	return 0;
}

DWORD WINAPI eventThreadTwo(LPVOID lp)
{
	cout<<"-----in eventThread Two-----"<<endl;
	DWORD res =WaitForSingleObject(hEvent,INFINITE);
	if (WAIT_OBJECT_0 == res)
	{
		cout<<"eventThread Two wait event"<<endl;
	}
	return 0;
}

void eventTest()
{
	
	//hEvent=CreateEvent(NULL,true,true,NULL);//场景1. 手动置为有信号,初始化为有信号  都运行
	//hEvent=CreateEvent(NULL,false,true,NULL); //场景2. 手动置为无信号,初始化为有信号    只有一个运行 
	//hEvent=CreateEvent(NULL,true,false,NULL); //场景3. 手动置为有信号,初始化为无信号  都不运行,只有reset有信号才运行 SetEvent(hEvent)
	hEvent=CreateEvent(NULL,false,false,NULL);//场景4. 手动置为无信号,初始化为无信号  都不运行,只有reset有信号才运行一个线程,

	if(!SetEvent(hEvent))//场景3,4 置为有信号 BOOL SetEvent(HANDLE hEvent);
	{
		cout<<"set event fail"<<endl;
	}

	if (!hEvent)
	{
		cout<<"create event failed"<<endl;
		return ;
	}
	hEventOne=CreateThread(0,0,eventThreadOne,0,0,0);
	Sleep(200);
	hEventTwo=CreateThread(0,0,eventThreadTwo,0,0,0);
	WaitForSingleObject(hEventOne,INFINITE);
	WaitForSingleObject(hEventTwo,INFINITE);
	CloseHandle(hEventTwo);
	CloseHandle(hEventOne);
	
	CloseHandle(hEvent);
	return;
}

4. TJ代码实现 以vad为例

主线程:
定义:
typedef HANDLE           VAThread_cond_t;
VAThread_cond_t		m_hCond;

创建事件对象
VAThreadCondInit(&m_hCond))
   CreateEvent(NULL, FALSE, FALSE, NULL);//手动置为无信号,初始化为无信号

设置为有信号
VAThreadSetSignal(&m_hCond);
   SetEvent(*cond)

执行线程:
先置为无信号,然后等待信号到来
VAThreadCondTimedWait(&m_hCond, &m_hMutex, 100)
   ResetEvent(*cond);
   ret = WaitForSingleObject(*cond, millisecond);

5. 参考

https://blog.csdn.net/u011642774/article/details/52789969

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值