本文共 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/