boost::condition cond;
boost::mutex access;
void listener_thread()
{
boost::mutex::scoped_lock lock(access);
while (true) {
while (!condition_check_var) {
cond.wait(lock);
}
do_some_work();
}
}
/// ... Main thread ...
cond.notify_all();
check_work:
{
boost::mutex::scoped_lock lock(access);
function_relies_on_work_been_done();
}
这是正确的设计吗?是否可以安全地假设一旦notify_all()
返回,listener_thread就已经获得了锁定?当check_work
块运行时(因为它锁定与listener_thread()
相同的互斥锁),listener_thread()
已经完成了一些“工作”?
如果没有,实现这种行为的首选方式是什么?
答案 0 :(得分:3)
无法保证任何其他线程已对通知采取行动,甚至收到通知。实际上,甚至没有保证当前有一个线程正在等待它的接收,尽管在你的设置中它看起来好像有可能存在线程等待的情况。如果要确保接收线程已完成其工作,则需要设置反向通信通道,例如,使用另一个条件变量和合适的条件。
我意识到你的问题是关于Boost的,但这是标准对此有何看法(30.5.1 [thread.condition.condvar]第8段):
void notify_all() noexcept;
效果:取消阻止等待*this
阻止的所有线程。
它不保证线程和/或任何涉及的互斥锁会发生什么。
答案 1 :(得分:1)
一般情况下,虽然写它的典型方法是这样的:
while (true)
{
cond.wait(lock, [&]() -> bool { return condition_check_var; });
do_some_work();
}
你不能说同时调用notify_all()
和wait()
,因为两者之间没有正式的因果关系。您需要知道的同步是,当wait()
返回时,您将获得锁定。由于您的check_work
块也会锁定互斥锁,因此只保证在另一个线程阻塞条件变量时执行。