试图理解条件变量

Posted

技术标签:

【中文标题】试图理解条件变量【英文标题】:trying to understand condition variables 【发布时间】:2020-05-08 09:24:44 【问题描述】:

我已经阅读了有关在两个或多个线程之间发出信号的条件变量。现在我试图理解我拥有的一些代码。我有(简化):

class Class
    void put(Something&& something)
        
            std::lock_guard<std::mutex> lock(a_mutex);
            // Do the operation here
            some_operation();
        
        cond_var.notify_one();
    
    
    std::unique_ptr<Something> get()
        std::unique_lock<std::mutex> lock(a_mutex);
   
        cond_var.wait(lock,[this]return someCondition());
    
        //Do the operation here
        auto res=some_other_operation();
        return res;
    
    
    std::mutex a_mutex;
    std::condition_variable cond_var;    
;

我可以理解put 获取锁并执行一些操作,然后通知任何等待解除阻塞的线程。 get 也会阻塞,直到条件变量被 put 发出信号,或者如果 someCondition 不为真则阻塞。一旦收到信号,它就会执行一些其他操作并返回它的值。

我不明白的是时机。

例如,假设调用了put 函数并发出通知,但没有线程在等待,因为get 尚未被调用。会发生什么?

然后假设get 被调用并阻塞。还是没有? (理想情况下它不应该因为有人已经先打电话给put)。

应该get 等到put 被调用再次

【问题讨论】:

【参考方案1】:

例如,假设调用了 put 函数并通知 但没有线程在等待,因为 get 尚未被调用。什么 发生了什么?

docs 说:*如果有任何线程正在等待 this,调用 notify_one 会解除对其中一个等待线程的阻塞。 如果有,那么如果没有什么特别的事情发生。 p>

然后假设 get 被调用并阻塞。还是没有?? (理想情况下 这不应该是因为有人已经调用了 put first)。

将有条件地阻止someCondition()。如果someOperation() 导致someCondition() 被实现,那么wait 将在notify_one() 被调用时解除阻塞,或者如果someCondition() 已经实现则根本不阻塞。

【讨论】:

谢谢。我正在消化你的解释:)尤其是最后一段。如果我错了,请纠正我......如果someCondition() 是真的,它不会被阻止?这是有道理的...... 没错。如果您调用等待并且条件为真,那么您将不会释放锁,不会等待并立即继续......如果您调用等待并且条件为假,那么您释放锁,放置在等待队列中,直到其他人调用通知,此时您将重新测试条件等。 这就是我弄错的地方。 wait 仅当条件为假时才释放锁并置于等待队列中? (顺便说一句,我有一个相关的问题) 话虽如此,而且这是多线程的,如果几乎同时调用 put 和 get 会发生什么?我想那里涉及互斥锁 @KansaiRobot 是互斥锁的目的是确保只有一个得到它,另一个被阻止。

以上是关于试图理解条件变量的主要内容,如果未能解决你的问题,请参考以下文章

理解 Linux 条件变量

C++ 条件变量范围

在 C 中的循环中重用条件变量

为啥“等待谓词”解决了条件变量的“丢失唤醒”?

条件变量与互斥量

`xcconfig` 文件中的条件用户定义变量