与conditional_variable一起使用时(unique)与unique_lock的开销

时间:2014-01-21 08:25:10

标签: c++ multithreading boost race-condition boost-mutex

为什么wait()的{​​{1}}方法需要boost::conditiona_variable个对象作为参数,而不是简单的boost::unique_lock

实际上,根本没有完全清楚unique_lock的用途。为什么我应该在boost::mutex周围创建另一个包装器对象,以及对性能的影响?

例如,假设我有两个主题boost::mutexthread1

on thread2

thread1

on 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对象会很浪费。你能否告诉我这些对象的目的以及它们是否会带来很大的开销?

谢谢!

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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