事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaled or true)或未激发状态(unsignal or false)。根据状态变迁方式的不同,事件可分为两类:
1.手动设置:这种对象只可能用程序手动设置,在需要该事件或者事件发生时,采用SetEvent及ResetEvent来进行设置。
2. 自动恢复:一旦事件发生并被处理后,自动恢复到没有事件状态,不需要再次设置。
使用”事件”机制应注意以下事项:
(1)如果跨进程访问事件,必须对事件命名,在对事件命名的时候,要注意不要与系统命名空间中的其它全局命名对象冲突;
(2)事件是否要自动恢复;
(3)事件的初始状态设置。
由于event对象属于内核对象,故进程B可以调用OpenEvent函数通过对象的名字获得进程A中event对象的句柄,然后将这个句柄用于ResetEvent、SetEvent和WaitForMultipleObjects等函数中。此法可以实现一个进程的线程控制另一进程中线程的运行,例如:
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, true, "MyEvent");
ResetEvent(hEvent);
************************* 注:以上概念来自于网络摘抄 *************************
下面看代码对比
使用事件编码时注意以下三点:
- HANDLE hEvent; // 定义事件句柄
- WaitForSingleObject(hEvent,INFINITE); 及 SetEvent(hEvent);
- hEvent = CreateEvent(NULL,FALSE,TRUE,NULL);
先看一下不加事件时的代码及输出:
#include
#include
using namespace std;int i = 0;
void aaa()
{for (int t &#61; 0; t < 5; t&#43;&#43;){i&#43;&#43;;cout << "线程1中 i &#61; " << i << endl;}
}
void bbb()
{for (int t &#61; 0; t < 5; t&#43;&#43;){i&#43;&#43;;cout << "线程2中 i &#61; " << i << endl;}}
int main(int argc, char* argv[])
{thread mythread(aaa); thread mythread2(bbb); mythread.join();mythread2.join();return 0;
}
输出&#xff1a;
没加事件的结论&#xff1a;
非常混乱 &#xff01;
再看一下加了事件时的代码及输出&#xff1a;
#include
#include
#include
#include
using namespace std;HANDLE hEvent;
int i &#61; 0;
void aaa()
{WaitForSingleObject(hEvent, INFINITE); for (int t &#61; 0; t < 5; t&#43;&#43;){i&#43;&#43;;cout << "线程1中 i &#61; " << i << endl;}SetEvent(hEvent);
}
void bbb()
{WaitForSingleObject(hEvent,INFINITE); for (int t &#61; 0; t < 5; t&#43;&#43;){i&#43;&#43;;cout << "线程2中 i &#61; " << i << endl;}SetEvent(hEvent);
}
int main(int argc, char* argv[])
{hEvent &#61; CreateEvent(NULL,FALSE,TRUE,NULL);thread mythread(aaa);thread mythread2(bbb);mythread.join();mythread2.join();return 0;
}
输出&#xff1a;
加了事件处理的总结&#xff1a;
有序输出&#xff0c;达到了线程同步的效果。自己感受一哈~~
结束&#xff1a;
分享也是自己对问题再次加深理解的方式&#xff0c;可能不全面&#xff0c;但绝对有用&#xff0c;后面将不断完善~