线程A:设置变量m_bPaused,m_pPauseEvent是一个提供wait()和set()接口的信号量对象。 线程A调用此方法暂停:
PausePlay(){
m_bPaused = true; // A1
m_pPauseEvent->Wait(0); //A2 wait for the B thread is enter to the waiting
}
主题B:
if (m_bPaused)
{
m_pPauseEvent->Set(); //B1
m_pPauseEvent->Wait(0); //B2 0 wait forever
}
并调用线程A继续线程B:
m_bPaused = false; //A3
m_pPauseEvent->Set(); //A4
当我暂停时,我等到B1被执行。线程A返回。这里是死锁吗?当我在线程A中调用continue时,运行到A3。同时,线程B仍然是B1和B2,那么A完成行m_pPauseEvent-> Set()。线程B永远不会收到A4发送的信号。死锁!这会发生吗?
答案 0 :(得分:2)
由于您未发布事件类的实现,因此代码中可能存在多个问题。
Set()
之前调用Wait(0)
。您确定线程A会收到通知吗或者线程B是否会使用该通知。所以很难判断这段代码是否会无死锁。
答案 1 :(得分:1)
不能肯定地说。 m_bPaused
可能是非原子变量,这意味着并发访问是未定义的行为。
答案 2 :(得分:0)
Windows事件不保证信号唤醒当前的服务员之一。这是PulseEvent
已知问题和错过唤醒的原因,因为事件已设置然后被清除,但等待线程可能看不到该集。
在这种情况下,Wait
调用之后的Set
调用可能会唤醒而不是另一个线程上的Wait
调用。这意味着没有同步保护对m_bPaused
的访问,即UB,也意味着错误的线程已经唤醒。