关于C++中的条件变量

发布于 2024-11-27 09:13:14 字数 1008 浏览 0 评论 0 原文

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

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 有何不同?

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

I am going through condition variable article at following location

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 );
        }
}

My understanding is that we use condition variable to wait on an event. I have following questions

  1. Why are we using mutex here while we are using condition
    variable?
  2. In consumer() function in while loop we are taking mutex and
    waiting on condition, how can producer function can lock mutex
    if consumer already taken it and how can it notify it doesn't it a deadlock?
  3. How unique_lock is different from scoped_lock?

Thanks for your help in clarfiying my questions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

给不了的爱 2024-12-04 09:13:14

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

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

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

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

它如何通知它不是死锁?

它不会死锁,因为 wait() 在使线程休眠之前释放锁。

unique_lock 与scoped_lock 有何不同?

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

Why are we using mutex here while we are using condition variable?

The basics of the condition variable require a lock to work correctly.
Only the thread with the lock should be trying to change the state of the condition variable (ie by calling one of the condition variable functions (it is also to protect the object you are really working on)).

In consumer() function in while loop we are taking mutex and waiting on condition, how can producer function can lock mutex if consumer already taken it

When you call wait() on the condition variable the thread is put to sleep and the mutex is released. When a thread is woken up it must re-acquire the lock before the function wait() returns to the user code.

and how can it notify it doesn't it a deadlock?

It does not deadlock because wait() is releasing the lock before putting the thread to sleep.

How unique_lock is different from scoped_lock?

In this context none. But if you have any specific implementation of these then please specify the implementation and we can discuss it in more detail.

笑红尘 2024-12-04 09:13:14

它应该是(为了清楚起见):

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&lock)

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

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

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

It should be (for clarity):

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 );
        }
}

From: http://www.boost.org/doc/libs/1_46_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref.condition_variable.wait
which is very similar.

void wait(boost::unique_lock& lock)

Precondition:
lock is locked by the current thread, and either no other thread
is currently waiting on *this, or the execution of the mutex() member
function on the lock objects supplied in the calls to wait or
timed_wait in all the threads currently waiting on *this would return
the same value as lock->mutex() for this call to wait.

Effects:
Atomically call lock.unlock() and blocks the current thread. The
thread will unblock when notified by a call to this->notify_one() or
this->notify_all(), or spuriously. When the thread is unblocked (for
whatever reason), the lock is reacquired by invoking lock.lock()
before the call to wait returns. The lock is also reacquired by
invoking lock.lock() if the function exits with an exception.

Postcondition:
lock is locked by the current thread.

假面具 2024-12-04 09:13:14

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

Mutex is for mutual exclusion (so that the producer & consumer don't alter global state without locking), condition variable is to impose some ordering.

〃温暖了心ぐ 2024-12-04 09:13:14
  1. 互斥体用于保护条件变量,
  2. 当您调用 my_condition.wait() 时,互斥体会自动解锁,当 my_conditioin.wait() 返回时,它会解锁互斥体,然后您可以在 while(!present) 中测试条件。也就是说,如果 wait() 由于另一个线程更快而无法锁定互斥锁,它将被阻塞。一旦更快的线程完成,此 wait() 返回并锁定互斥体,但条件可能变为 false,然后线程再次等待。因此,正如第一个答案所述,互斥锁用于保护条件变量。
  1. The mutex is used to protect the condition variable
  2. the mutex is unlocked automatically when you invoke my_condition.wait(), and when my_conditioin.wait() return, it unlock the mutex, then you can test the condition in while(!present). That's, if wait() can't lock the mutex because another thread is faster, it will be blocked. Once the faster thread finished, this wait() returned with mutex locked, but the condition maybe become false, then the thread wait again. So, the mutex is use to protect the condition varaible, as the 1st answer said.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文