如何使用boost条件变量来等待线程完成处理
How do I use a boost condition variable to wait for a thread to complete processing?
我使用一个条件变量来停止一个线程,直到另一个线程完成处理它的任务队列(长话短说)。因此,在一个线程上,我锁定并等待:
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
,那么你就会在没有调用wait()
的情况下直接陷入while循环。
这个模式是如此普遍,以至于我几乎可以说,如果你没有一个while
循环包装你的condition_variable.wait()
,那么你总是有一个错误。事实上,当c++ 11采用类似boost:: condition_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;});
在讨论的基础上,我已经实现了一个示例来说明如何使用boost条件。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
boost::mutex io_mutex;
bool worker_is_done = false;
boost::condition_variable condition;
void workFunction()
{
std::cout << "Waiting a little..." << std::endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
worker_is_done = true;
std::cout << "Notifying condition..." << std::endl;
condition.notify_one();
std::cout << "Waiting a little more..." << std::endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
int main()
{
boost::mutex::scoped_lock lock(io_mutex);
boost::thread workThread(&workFunction);
while (!worker_is_done) condition.wait(lock);
std::cout << "Condition notified." << std::endl;
workThread.join();
std::cout << "Thread finished." << std::endl;
return 0;
}
升压条件变量示例
相关文章:
- 将更高的优先级设置为 boost::asio 线程处理进程
- C++ 使用 2 个容器进行线程处理
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 多线程处理中的静态成员变量
- Opencv cpp 使用多线程处理同一视频的不同部分
- 对象析构函数在多线程处理时不断被调用,但该对象并未超出范围
- 使用 wxWidgets 进行多线程处理时出现奇怪的行为
- 使用共享变量进行线程处理
- 通过多线程处理确定每个字符在文件中出现的次数
- 使用多线程处理的异步请求
- 多线程处理,同时保持部分序列
- 如何在类中进行 c++ 多线程处理(将线程引用保留为成员 var)
- 用管道在C++中创建调度队列/线程处理程序:FIFO溢出
- 用多个线程处理SIGTERM的正确方法
- 使用C++的递归线程处理会使资源暂时不可用
- SDL 带变量的多线程处理 -- 无法按预期工作
- 使用多线程处理对象数组 - 无效使用 void 表达式错误
- 如何使用"priority"进行多线程处理?
- 使用简单的过程进行慢速多线程处理
- C++11 使用共享对象的多线程处理