C ++ Boost:2个线程之间的变量同步

Posted

技术标签:

【中文标题】C ++ Boost:2个线程之间的变量同步【英文标题】:C++ Boost :Variable sync between 2 threads 【发布时间】:2014-08-11 15:52:14 【问题描述】:

我有以下代码:

主线程通知工作线程开始/停止一些工作。在主线程中,触发器是一些 UI 按钮(本例中为 Qt SDK):

    void PlaySlot(bool checked)
        boost::unique_lock<boost::mutex> lock(m_mutex);
        if(checked == true)

            m_isPlayMode = true;
            m_event.notify_one(); //tell thread to  start playing.
         else

            m_isPlayMode = false;
        

    

现在,在工作线程中,一旦 m_isPlayMode 为真,一些循环开始运行一段有限的时间,并在时间结束或 m_isPlayMode 时退出变成假的。

线程操作符内部:

    while(true)
   

      boost::unique_lock<boost::mutex> lock(m_mutex);
      m_event.wait(lock); //wait for next event
      if(m_isPlayMode == true)

          while(m_frameIndex< totalFrames && m_isPlayMode)

           m_frameIndex++;
           ///do some work

          

        m_isPlayMode = false;
        emit playEnded(false);

     

  

现在,在循环开始播放后发生了什么,当 PlaySlot() 被 'checked' = false 触发时,它不会更新 m_isPlayMode 并且程序变得无响应。我怀疑这是条件竞争问题,因为我正在尝试锁定已经锁定在线程循环中的互斥锁。

我通过从 PlaySlot 方法中删除 unique_lock 并将 m_isPlayMode 转换为原子变量来解决它。它有效。

但我想知道两件事:

    这样的解决方案有什么危险吗?

    可以用其他方法解决吗?

【问题讨论】:

【参考方案1】:

请注意,m_isPlayMode 受相同的互斥锁保护,因此无法在 worker 运行时更新。为这些或原子使用两个单独的互斥锁。

编辑:快速修复可能会添加第二个互斥锁:

void PlaySlot(bool checked)
    boost::unique_lock<boost::mutex> lock(m_isPlayModeMutex); // <--
    // ...

工作线程:

for (;;) 
  boost::unique_lock<boost::mutex> lock(m_mutex);
  m_event.wait(lock); // wait for next event

  boost::unique_lock<boost::mutex> playModeLock(m_isPlayModeLock);
  if(m_isPlayMode == true)
    while(m_frameIndex< totalFrames && m_isPlayMode)
      playModeLock.unlock();
      /// ... (not locked here)
      playModeLock.lock();
    
    m_isPlayMode = false;
    emit playEnded(false);
  

【讨论】:

你认为在这种情况下原子操作更好吗? @michael-iv 如果您只需要一个标志,那么可能是的。 注意,如果m_mutex是原子的,则不需要将PlaySlot锁定。 如果m_isPlayMode 是一个原子原语,互斥体无关紧要。如果不是,请在使用它的地方周围使用互斥锁。 好吧,在上面的例子中,m_isPlayMode 不是原子的。我不使用原子版本的互斥锁。

以上是关于C ++ Boost:2个线程之间的变量同步的主要内容,如果未能解决你的问题,请参考以下文章

两个线程c ++之间的boost asio通信

在 C++11 中实现 boost::barrier

java多线程理解2

java中的volatile变量

c ++ boost线程问题[关闭]

java多线程有几种实现方法?线程之间如何同步