c++ - 如何使用 boost 条件变量来等待线程完成处理?

标签 c++ multithreading boost

我正在使用条件变量来停止一个线程,直到另一个线程完成处理它的任务队列(长篇大论)。所以,我在一个线程上锁定并等待:

boost::mutex::scoped_lock lock(m_mutex);
m_condition.wait(lock);

一旦另一个线程完成了它的任务,它就会向等待的线程发出如下信号:

boost::mutex::scoped_lock lock(m_parent.m_mutex);
m_parent.m_condition.notify_one();

我看到的问题是等待线程不会停止等待,除非我在它后面的指令上设置断点(我使用的是 xcode,仅供引用)。是的,这看起来很奇怪。有谁知道为什么会发生这种情况?我是否误用了条件变量?

最佳答案

是的,您误用了条件变量。 “条件变量”实际上只是信号机制。您还需要测试一个条件。在您的情况下,可能发生的是调用 notify_one() 的线程实际上在调用 wait() 的线程甚至开始之前完成。 (或者至少,notify_one() 调用发生在 wait() 调用之前。)这称为“错过唤醒”。

解决方案是实际上有一个包含您关心的条件的变量:

bool worker_is_done=false;

boost::mutex::scoped_lock lock(m_mutex);
while (!worker_is_done) m_condition.wait(lock);

boost::mutex::scoped_lock lock(m_mutex);
worker_is_done = true;
m_condition.notify_one();

如果 worker_is_done==true 在其他线程甚至开始等待之前,那么您将直接进入 while 循环,而无需调用 wait()

这种模式非常普遍,以至于我几乎可以说,如果您没有包装 condition_variable.wait()while 循环那么你总是有一个错误。事实上,当 C++11 采用类似于 boost::condtion_variable 的东西时,他们添加了一种新的 wait() ,它接受一个谓词 lambda 表达式(本质上它为你执行 while 循环):

std::condition_variable cv;
std::mutex m;
bool worker_is_done=false;


std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return worker_is_done;});

关于c++ - 如何使用 boost 条件变量来等待线程完成处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16907072/

相关文章:

c++ - 加入特定的 boost 线程

C++ boost库shared_memory_object undefined reference 'shm_open'

c++ - 没有光照计算时我应该忽略顶点法线吗?

c++ - 正确的 C++ 指针语法

c++ - 多线程程序中的 MPI_Isend/MPI_Recv

Java线程notify()方法

JavaFX UI 创建和进度条更新

c++ - 为什么 boost locale 不提供字符级规则类型?

c++ - 英特尔 C++ 编译器无法处理深度模板?

c++ - 在 Windows 中,如何拥有作为重定向管道的非阻塞标准输入?