首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在这段代码中,wait()调用是如何使用notify调用的?

在这段代码中,wait()调用是如何使用notify调用的?
EN

Stack Overflow用户
提问于 2021-07-23 21:55:23
回答 1查看 54关注 0票数 0

我有一个c++代码,如下所示,它使用condition-variable进行同步。

代码语言:javascript
复制
#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; 
}

观察到的产出如下:

问题:

在开始时,如何触发foo()中的foo()

据我所读,带有谓词的wait()调用相当于:while (!pred()) { wait(lock); }。谓词在开头为true ( turn的初始值为Turn::FOO),但是等待调用如何获得通知?关于wait(),我看到如下:

原子地解锁锁,阻塞当前正在执行的线程,并将其添加到等待*this的线程列表中。当执行notify_all()或notify_one()时,线程将被解除阻塞。它也可能是伪造的。解除阻塞时,不管原因如何,重新获取锁并等待退出。

但我看不到另一个线程(运行bar()的线程)执行notify_one(),因为turn仍然是FOO

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-23 22:09:50

foo()内部的cv.wait在开始时是如何触发的?

它将由对true的谓词求值触发。等效循环:

代码语言:javascript
复制
while (!pred()) {
    wait(lock);
}

甚至一次都不会调用wait() (无论如何,这是第一次访问这一行代码)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68505381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档