您的位置:首页 > 大数据 > 人工智能

WaitForSingleObjec等待Event成功引起的副作用

2012-12-13 18:13 337 查看
一个自动重置事件的对象,WaitForSingleObject在等待成功以后会把事件对象设置为未触发状态(马上调用ResetEvent()函数),而手动设置事件对象不会有这个副作用。

#include <iostream>
#include <process.h>
#include <windows.h>
#include <string>
using std::cout;
using std::endl;
using std::string;

const int num=10;
int count;
HANDLE ThreadEvent;
unsigned __stdcall ThreadFun(void* par);

int main()
{
//创建内核事件对象(自动重置,未激活状态)
ThreadEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
HANDLE handles[num];
for(int i=0;i<num;++i)
{
handles[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,0);
WaitForSingleObject(ThreadEvent,INFINITE);
//自动激活状态的事件,WaitForSingleObject带来的副作用就是会自己调用ResetEvent()将事件设置为未激活
}
for(int i=0;i<num;++i)
CloseHandle(handles[i]);
CloseHandle(ThreadEvent);//关闭内核事件对象
system("PAUSE");
return 0;
}
unsigned __stdcall ThreadFun(void* par)
{
cout<<"count:"<<++count<<endl;
SetEvent(ThreadEvent);//设置事件为激活状态
return 0;
}




把事件对象设置为手动重置,就需要我们手动重置事件状态。

int main()
{
//创建内核事件对象(手动重置,未激活状态)
ThreadEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
HANDLE handles[num];
for(int i=0;i<num;++i)
{
handles[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,0);
WaitForSingleObject(ThreadEvent,INFINITE);
//手动激活的事件,WaitForSingleObject不会重置事件为未激活。
ResetEvent(ThreadEvent);//手动重置事件对象为未激活状态
}
for(int i=0;i<num;++i)
CloseHandle(handles[i]);
CloseHandle(ThreadEvent);//关闭内核事件对象
system("PAUSE");
return 0;
}


上面代码内核事件对象为手动重置,所以在WaitForSingleObject以后需要手动调用ResetEvent(),如果把ResetEvent(ThreadEvent);注释掉,那么所以等待线程都会被触发,导致同步失败。

for(int i=0;i<num;++i)
{
handles[i]=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,0);
WaitForSingleObject(ThreadEvent,INFINITE);
//手动激活的事件,WaitForSingleObject不会重置事件为未激活。
//ResetEvent(ThreadEvent);//后面的线程都会很顺利的执行,事件对象一直为激活状态
}




线程执行同步失败,输出混乱,可以将num变量设置大点,这样更加容易出现混乱输出。

本文版权归kennyMc和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: