2

我正在以下位置浏览条件变量文章

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循环中的消费者()函数中,我们正在使用互斥锁并在条件下等待,如果消费者已经使用了互斥锁,生产者函数如何锁定它,它如何通知它不是死锁?
  3. unique_lock 与 scoped_lock 有何不同?

感谢您帮助澄清我的问题。

4

4 回答 4

3

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

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

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

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

它如何通知它不是死锁?

它不会死锁,因为 wait() 在让线程进入睡眠状态之前释放了锁。

unique_lock 与 scoped_lock 有何不同?

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

于 2011-08-01T06:21:16.300 回答
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 非常相似。

无效等待(升压::unique_lock&锁)

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

效果:原子调用 lock.unlock() 并阻塞当前线程。当调用 this->notify_one() 或 this->notify_all() 或虚假通知时,线程将解除阻塞。当线程被解除阻塞时(无论出于何种原因),在调用等待返回之前调用 lock.lock() 重新获取锁。如果函数因异常退出,还可以通过调用 lock.lock() 重新获取锁。

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

于 2011-08-01T05:16:25.177 回答
0

互斥是为了互斥(这样生产者和消费者在没有锁定的情况下不会改变全局状态),条件变量是为了强加一些顺序。

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