1
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()?

如果不是,那么实现这种行为的首选方法是什么?

4

2 回答 2

3

无法保证任何其他线程已根据通知采取行动,甚至尚未收到通知。事实上,甚至不能保证当前有一个线程在等待它的接收,尽管在您的设置中看起来很可能有线程在等待。如果你想确保接收线程已经完成了它们的工作,你需要建立一个反向通信通道,例如,使用另一个条件变量和一个合适的条件。

我意识到您的问题是关于 Boost 的,但这是标准对此的看法(30.5.1 [thread.condition.condvar] 第 8 段):

void notify_all() noexcept; 效果:解除所有被阻塞等待的线程*this

它不保证线程和/或任何涉及的互斥锁会发生什么。

于 2012-11-25T23:57:17.717 回答
1

一般没问题,虽然典型的写法是这样的:

while (true)
{
    cond.wait(lock, [&]() -> bool { return condition_check_var; });
    do_some_work();
}

你不能说 callnotify_all()和 return 的同时性wait(),因为两者之间没有正式的因果关系。对于同步,您只需要知道当wait()返回时您将获得锁。由于您的check_work块还锁定了互斥锁,因此保证仅在其他线程阻塞条件变量时才执行。

于 2012-11-25T23:50:05.067 回答