0

线程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发送的信号。死锁!这会发生吗?

4

3 回答 3

2

由于您没有发布事件类的实现,因此您的代码中可能存在多个问题。

  1. 如前所述,您对 m_bPaused 的访问可能是一个问题。
  2. 线程 BSet()Wait(0). 您确定线程 A 会收到通知还是线程 B 会使用通知。
  3. 在几乎所有的多线程类中都存在虚假唤醒的问题。您的线程 B 似乎不受此保护。

所以很难判断这段代码是否会无死锁。

于 2013-01-30T09:09:12.540 回答
1

不能肯定地说。m_bPaused可能是一个非原子变量,这意味着并发访问是未定义的行为。

于 2013-01-30T08:56:08.793 回答
0

Windows 事件不保证信号会唤醒当前的服务员之一。这是已知问题PulseEvent和错过唤醒的原因,因为事件已设置然后清除,但等待线程可能看不到该设置。

在这种情况下,Wait调用之后的Set调用可能会唤醒,而不是Wait另一个线程上的调用。这意味着对 UB 的访问没有同步保护m_bPaused,也意味着唤醒了错误的线程。

于 2013-01-30T14:27:34.550 回答