我想知道如何在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()
操作的任何细节答案 0 :(得分:0)
我刚注意到的一件事:你为什么要将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;
}