如果在wait()之前调用notify()怎么办?

rah*_*man 12 c++ synchronization boost condition-variable ns-3

我有一种情况,可以在wait()之前调用notify()'.

当我通过向他发送消息通知他时,我正在尝试制作一个模拟器来安排下一个事件.所以我设计了一个wait-> notify-> scedule链

void Broker::pause()
{
    boost::unique_lock<boost::mutex> lock(m_pause_mutex);
    {
        std::cout << "pausing the simulation" << std::endl;
        m_cond_cnn.wait(lock);
        std::cout << "Simulation UNpaused" << std::endl;
        // the following line causes the current function to be called at 
        // a later time, and a notify() can happen before the current function
        // is called again
        Simulator::Schedule(MilliSeconds(xxx), &Broker::pause, this);
    }
}

void Broker::messageReceiveCallback(std::string message) {
    boost::unique_lock<boost::mutex> lock(m_pause_mutex);
    {
        m_cond_cnn.notify_one();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是:可能存在在调用wait()之前调用notify()的情况.

这种情况有解决方案吗?谢谢

sya*_*yam 14

条件变量很难单独使用,只是因为,正如您所注意到的那样,它们只唤醒当前正在等待的线程.还有虚假唤醒的问题(即,条件变量有时可以唤醒线程而没有任何相应的notify被调用).要正常工作,条件变量通常需要另一个变量来维持更可靠的状态.

要解决这两个问题,在您的情况下,您只需要添加一个布尔标志:

boost::unique_lock<boost::mutex> lock(m_pause_mutex);
while (!someFlag)
    m_cond_cnn.wait(lock);
someFlag = false;

//...

boost::unique_lock<boost::mutex> lock(m_pause_mutex);
someFlag = true;
m_cond_cnn.notify_one();
Run Code Online (Sandbox Code Playgroud)

  • @kroiz 在这种情况下否:访问受互斥体保护。如果某些代码在没有先锁定互斥体的情况下访问它,则它需要是原子的。 (3认同)
  • 我想知道为什么 C++11 和 pthreads 将其称为“条件变量”,尽管它是完全无状态的并且像裸信号/事件一样工作,而 WinAPI 将其称为“事件”,而它在那里像同步布尔标志一样工作。难道不应该反过来吗? (2认同)