关于C ++中的条件变量

时间:2011-08-01 05:05:05

标签: c++ tbb

我将在以下位置阅读条件变量文章

http://software.intel.com/en-us/blogs/2010/10/01/condition-variable-support-in-intel-threading-building-blocks/

Here we have following code as example

#include "tbb/compat/condition_variable"  
using namespace std;
condition_variable my_condition;
tbb::mutex my_mtx;
bool present = false;

void producer() {
        unique_lock<tbb::mutex> ul( my_mtx );
        present = true;
        my_condition.notify_one();
}

void consumer() {
        while( !present ) {
            unique_lock<tbb::mutex> ul( my_mtx );
            my_condition.wait( ul );
        }
}

我的理解是我们使用条件变量来等待事件。我有以下问题

  1. 为什么我们在使用条件时会在这里使用互斥锁 变量?
  2. 在while循环中的consumer()函数中,我们正在使用互斥锁和     等待条件,生产者函数如何能锁定互斥锁 如果消费者已经采取了它,它如何通知它不是一个僵局?
  3. unique_lock与scoped_lock有何不同?
  4. 感谢您帮助我澄清我的问题。

4 个答案:

答案 0 :(得分:3)

  

为什么我们在使用条件变量时会在这里使用互斥?

条件变量的基础知识需要锁才能正常工作 只有带锁的线程才应该尝试更改条件变量的状态(即通过调用其中一个条件变量函数(它也是为了保护你正在处理的对象)。)

  

在while循环中的consumer()函数中,我们正在使用互斥量并等待条件,如果消费者已经采用它,生产者函数如何能锁定互斥锁

当您对条件变量调用wait()时,线程将进入休眠状态并释放互斥锁。当一个线程被唤醒时,它必须在函数wait()返回到用户代码之前重新获取锁。

  

如何通知它不是一个死锁?

它没有死锁,因为wait()在让线程进入休眠状态之前释放锁。

  

unique_lock与scoped_lock有何不同?

在这种情况下没有。但是如果你有任何具体的实现,那么请指定实现,我们可以更详细地讨论它。

答案 1 :(得分:1)

应该(为了清楚起见):

void producer() {
        unique_lock<tbb::mutex> ul( my_mtx ); // protect present
        present = true;
        my_condition.notify_one();
}

void consumer() {
        unique_lock<tbb::mutex> ul( my_mtx );   // protect preset
        while( !present ) {
            my_condition.wait( ul );
        }
}

来自:http://www.boost.org/doc/libs/1_46_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref.condition_variable.wait 这是非常相似的。

  

void wait(boost :: unique_lock&amp; lock)

     

前提条件:       锁被当前线程锁定,并且没有其他线程   正在等待* this,或执行mutex()成员   对等待或调用中提供的锁定对象的函数   在当前等待的所有线程中的timed_wait *将返回   与此次调用等待的lock-&gt; mutex()值相同。

     

效果:       原子调用lock.unlock()并阻塞当前线程。该   线程将在通过调用this-&gt; notify_one()或通知时解除阻止   this-&gt; notify_all(),或者是虚假的。线程解除阻塞时(for   无论什么原因),通过调用lock.lock()重新获取锁定   在等待调用之前返回。锁也被重新获取   如果函数以异常退出,则调用lock.lock()。

     

后置条件:   锁被当前线程锁定。

答案 2 :(得分:0)

Mutex用于互斥(因此生产者和消费者不会在没有锁定的情况下改变全局状态),条件变量是强加一些排序。

答案 3 :(得分:0)

  1. 互斥锁用于保护条件变量
  2. 当您调用my_condition.wait()时,互斥锁会自动解锁,当my_conditioin.wait()返回时,它会解锁互斥锁,然后您可以在while(!present)中测试条件。也就是说,如果wait()无法锁定互斥锁,因为另一个线程更快,它将被阻止。一旦更快的线程完成,这个wait()返回时锁定互斥锁,但条件可能变为false,然后线程再次等待。因此,正如第一个答案所说,互斥锁用于保护可变条件。