简体   繁体   English

在这段代码中,wait() 调用是如何通过通知调用的?

[英]How does the wait() call get invoked with notify in this code?

I have a c++ code as follows that uses condition-variable for synchronization.我有一个 C++ 代码,如下所示,它使用condition-variable进行同步。

#include <iostream> 
#include <condition_variable>

int n = 4;
enum class Turn { FOO, BAR };
Turn turn = Turn::FOO;

std::mutex mut;
std::condition_variable cv;

void foo() {
    for (int i = 0; i < n; i++) {
        std::unique_lock<std::mutex> lock(mut);

        // wait for signal from bar & turn == FOO
        cv.wait(lock, [] {return turn == Turn::FOO; });

        std::cout << "foo" << std::endl;

        // unlock & signal bar
        lock.unlock();
        turn = Turn::BAR;
        cv.notify_one();
    }
}

void bar() {
    for (int i = 0; i < n; i++) {
        std::unique_lock<std::mutex> lock(mut);

        // wait for signal from foo & turn == BAR
        cv.wait(lock, [] {return turn == Turn::BAR; });

        std::cout << "bar" << std::endl;

        // unlock &  signal foo
        lock.unlock();
        turn = Turn::FOO;
        cv.notify_one();
    }
}

int main() {
    std::thread thread_1(foo);
    std::thread thread_2(bar);
    thread_2.join();
    thread_1.join();
    
    return 0; 
}

The output observed:观察到的输出:

输出

Question:问题:

How would the cv.wait(lock, [] {return turn == Turn::FOO; }); cv.wait(lock, [] {return turn == Turn::FOO; }); inside the foo() get triggered in the beginning?foo()里面一开始就被触发?

From what I read, the wait() call with the predicate would be equivalent to: while (!pred()) { wait(lock); }从我读到的,带有谓词的wait()调用等效于: while (!pred()) { wait(lock); } while (!pred()) { wait(lock); } . while (!pred()) { wait(lock); } . The predicate is true at the beginning (the initial value of turn is Turn::FOO ), but how would the wait call get a notify?谓词一开始为真( turn的初始值为Turn::FOO ),但是等待调用如何获得通知呢? Regarding wait() , I see this:关于wait() ,我看到了这个:

Atomically unlocks lock, blocks the current executing thread, and adds it to the list of threads waiting on *this.原子地解锁锁,阻塞当前正在执行的线程,并将其添加到等待 *this 的线程列表中。 The thread will be unblocked when notify_all() or notify_one() is executed.当notify_all() 或notify_one() 被执行时,线程将被解除阻塞。 It may also be unblocked spuriously.它也可能被虚假地解除阻塞。 When unblocked, regardless of the reason, lock is reacquired and wait exits.解除阻塞时,无论何种原因,都会重新获取锁并等待退出。

But I don't see the other thread's (the one running bar() ) to have it's notify_one() executed since turn is still FOO .但是我没有看到另一个线程(正在运行bar()notify_one()执行notify_one()因为turn仍然是FOO

How would the cv.wait inside the foo() get triggered in the beginning? foo()的 cv.wait 如何在开始时被触发?

It would be triggered by the predicate evaluating to true .它将由评估为true的谓词触发。 The equivalent loop:等效循环:

while (!pred()) {
    wait(lock);
}

would not call wait() even once (the first time that line of code is visited, anyway).甚至不会调用wait()一次(无论如何都是第一次访问该行代码)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM