boost :: condition :: notify_all是否保证侦听器线程在返回之前获取锁定?

时间:2012-11-25 23:35:33

标签: c++ multithreading boost synchronization

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()已经完成了一些“工作”?

如果没有,实现这种行为的首选方式是什么?

2 个答案:

答案 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块也会锁定互斥锁,因此只保证在另一个线程阻塞条件变量时执行。