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个线程之间的变量同步的主要内容,如果未能解决你的问题,请参考以下文章