3

为什么 a 的wait()方法boost::conditiona_variable需要一个boost::unique_lock对象作为参数而不是简单的boost::mutex

实际上,unique_lock 的用途并不完全清楚。为什么要在我的 周围创建另一个包装器对象boost::mutex,对性能有什么影响?

例如,假设我有两个线程,thread1并且thread2

thread1

void process() {
  while(true){
    while (objectToProcess == NULL) {
      boost::unique_lock lock(mutex);
      waitingVariable.wait(lock);
    }

    doSomething(objToProcess);

    objToProcess = NULL;
    waitingVariable.notify();
  }
}

thread2

void feedProcessor() {
  while(true) {
        while (objectToProcess != NULL) {
          boost::unique_lock lock(mutex);
          waitingVariable.wait(lock);
        }

        objToProcess = createNewObjectToProcess();
        waitingVariable.notify();
  }
}

unique_lock在这种情况下,我发现每次需要调用wait()条件变量的方法时都创建新对象是很浪费的。您能否告诉我这些对象的目的以及它们是否会引入大量开销?

谢谢!

(我看到我的问题与这个问题重叠,但我更关心的是开销而不是目的......)

4

2 回答 2

1

传入 std::unique_lock 而不是互斥锁可确保您满足等待功能的要求,即为其提供已锁定的互斥锁。如果你可以传入一个互斥锁,你可以传入一个未锁定的实例,这样等待函数要么必须失败,这意味着以某种方式处理错误,要么有未定义的行为,这不是一件好事。

在优化的构建中,使用加法对象可能没有开销超过手动锁定互斥锁(并记住这样做,并根据需要正确解锁)

于 2014-01-21T12:14:22.800 回答
0

条件变量的思想如下:

您可以通过 unique_lock 保护异步事件的消耗。但是,如果条件变量至少有一个尚未使用的事件可用,则您只锁定互斥锁。否则,锁不会被锁定,而是等待通知事件。

有了这种理解,您的代码应该更改为以下内容,以保护您对对象的处理:

boost::unique_lock lock(mutex);
while (objectToProcess == NULL) {

  waitingVariable.wait(lock);
}

http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref

于 2014-01-21T09:20:41.650 回答