Windows setevent处理
我想知道在Windows内部如何处理setevent。
我有以下情况
Std :: thread线程循环,它执行时std :: atomic == true循环内部是一个waitforsingleObject,它以可警告状态休眠无限。
一个函数stopThread(),它执行以下操作: - 清除原子布尔值 - 在事件对象上调用Setevent - 调用thread.join
这经常会挂起,我得到的印象是setevent在当前线程中仍有一些工作要做,而加入阻止当前线程。
如果我在waitforsinlgleObject之后设置的线程中添加一个额外的布尔值,并且在调用join()之前等待它设置,那么一切似乎都可以正常工作。
代码(这里省略错误检查)
初始化代码/声明:
HANDLE m_WakeupThreadEvent;
std::atomic<bool> m_ReceiverEnabled;
m_WakeupThreadEvent = CreateEvent(NULL, false, false, "RxThreadWakeupEvent" );
线程代码:
while(m_ReceiverEnabled)
{
DWORD rslt = WaitForSingleObjectEx(m_WakeupThreadEvent, INFINITE, true);
// Here some checking for rslt;
}
功能码:
m_ReceiverEnabled = true;
SetEvent( m_WakeupThreadEvent )
m_Thread.join()
有这种行为的解释吗? 我找不到有关setEvent()的操作的任何细节
有一件事我只是注意到:你为什么将m_ReceiverEnabled
设置为true
? 它应该设置为false
。 我在下面的代码中做了这个。
即使您确定竞赛状况不是您问题的根源,但由于使用了自动重置事件,您仍然有竞争状况。 你能解决它,然后看看这是否也恰好照顾你的主要问题? 这里是代码,它使用手动重置事件而不是以无竞争的方式:
HANDLE m_WakeupThreadEvent;
std::atomic<bool> m_ReceiverEnabled;
m_WakeupThreadEvent = CreateEvent(NULL, TRUE, FALSE, "RxThreadWakeupEvent" );
m_ReceiverEnabled = false;
SetEvent( m_WakeupThreadEvent )
m_Thread.join()
while(true)
{
DWORD rslt = WaitForSingleObjectEx(m_WakeupThreadEvent, INFINITE, true);
ResetEvent(m_WakeupThreadEvent);
if(!m_ReceiverEnabled)
break;
// Here some checking for rslt;
}
链接地址: http://www.djcxy.com/p/5205.html