博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++的CreateEvent
阅读量:4093 次
发布时间:2019-05-25

本文共 2920 字,大约阅读时间需要 9 分钟。

一、事件是很常用的多线程同步互斥机制

函数原型如下所示,一共四个参数:

HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构指针,可为NULL BOOL bManualReset,     // 手动/自动                                     // TRUE:表示手动,在WaitForSingleObject后必须手动调用ResetEvent清除信号                                    // FALSE:表示自动,在WaitForSingleObject后,系统自动清除事件信号 BOOL bInitialState,        //初始状态,FALSE为无信号,TRUE为有信号 LPCTSTR lpName         //事件的名称    );

SetEvent是用来设定事件为有信号,ResetEvent设置事件为无信号。

那事件有信号和无信号到底有什么用,又是怎么用的呢?可以想象以下这样的场景,比如一群人在等候就餐,服务员喊道:38号(有信号)。那38号顾客就可以去就餐,对于那些没被叫道号(无信号)则需继续排队。同样如此,对于多线程只有当该线程有信号时,才能获取CPU事件进而执行相关操作;如果没有信号,则只能继续排队等待(处于阻塞状态)

那线程是怎么获取这时候是否有信号呢?通过WaitForSingleObject函数,下面看函数介绍

This function returns when the specified object is in the signaled state or when the time-out interval elapses.         DWORD WaitForSingleObject(     HANDLE hHandle,     DWORD dwMilliseconds );     第一个参数指明对象句柄,我们可以把创建的事件句柄赋予它    第二个参数表明wait时间。我就等你三年,三年等不到就结婚了....    最重要的是通过返回值来做进一步操作,该函数主要有几个返回值:    WAIT_ABANDONED——说明句柄代表的对象是个互斥对象,并且正在被其它线程占用。意思就是说哥们你得等等,我还没完事呢    WAIT_OBJECT_0——说明句柄对象处于有信号状态    WAIT_TIMEOUT——在指定的时间内得不到答复(等待超时)且句柄对象处于无信号状态。意思就是你是个好人,今生别等了,下辈子见吧

 

 

二、下面是使用演示

实例一

CreateEvent(NULL, TRUE, TRUE, NULL)——初始状态为有信号,且需手动重置才能为无信号的事件

HANDLE g_hEvent;DWORD WINAPI procFunc1(LPVOID lpParam){	cout << "start thread1" << endl;	if (WaitForSingleObject(g_hEvent, 1) == WAIT_OBJECT_0)	{		cout << "thread1 is working..." << endl;	}	cout << "leve thread1..." << endl;	return 0;}DWORD WINAPI procFunc2(LPVOID lpParam){	cout << "start thread2" << endl;	if (WaitForSingleObject(g_hEvent, 1) == WAIT_OBJECT_0)//有信号,继续执行	{		cout << "thread2 is working..." << endl;	}	cout << "leve thread2..." << endl;	return 0;}int main(){	g_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)procFunc1, NULL, 0, NULL);	Sleep(500);	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)procFunc2, NULL, 0, NULL);        return 0}

可以看到线程1和线程2都完整执行了。因为创建的事件是需手动Reset才会无信号的,所以执行完线程1后事件仍处于有信号状态,所以线程2才能被继续执行

实例二、

再看另一个场景:CreateEvent(NULL, FALSE, TRUE, NULL)——初始状态为有信号且无需手动重置才能为无信号的事件

代码与上几乎相同,区别在与创建事件时参数

 输出

可以看到线程1完整执行了,但是由于信号在执行完线程1后被自动重置为无信号,所以线程2中的逻辑没被执行

实例三、使用SetEvent,ResetEvent

HANDLE g_hEvent = NULL;DWORD WINAPI procFunc1(LPVOID lpParam){	cout << "start thread1" << endl;	if (WaitForSingleObject(g_hEvent, 1) == WAIT_OBJECT_0)	{		cout << "thread1 is working..." << endl;	}	cout << "leve thread1..." << endl;	ResetEvent(g_hEvent);//重置事件为无信号	return 0;}DWORD WINAPI procFunc2(LPVOID lpParam){	cout << "start thread2" << endl;	if (WaitForSingleObject(g_hEvent, 1) == WAIT_OBJECT_0)//因为没信号,所以不会执行	{		cout << "thread2 is working..." << endl;	}	cout << "leve thread2..." << endl;	return 0;}int main(){	g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);	SetEvent(g_hEvent);	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)procFunc1, NULL, 0, NULL);	Sleep(500);	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)procFunc2, NULL, 0, NULL);}

 

参考:

 

转载地址:http://akiii.baihongyu.com/

你可能感兴趣的文章
PCI总线设备遍历
查看>>
硬件中断信号处理
查看>>
Linux_rtl8169
查看>>
CPU Temp hardware monitor
查看>>
PCI总线与HT总线
查看>>
setup_early_printk()函数分析
查看>>
printk()函数分析
查看>>
device_tree分析
查看>>
中断域
查看>>
总线注册(platform,PCI)
查看>>
qemu-qdev
查看>>
qemu-sysbus
查看>>
qemu-QemuOpt
查看>>
网络子系统
查看>>
sock文件系统
查看>>
ftrace_init
查看>>
ftrace
查看>>
Linux程序设计——信号
查看>>
Linux程序设计——线程
查看>>
进程之间的通信——管道
查看>>