我有一个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;
}观察到的产出如下:

问题:
在开始时,如何触发foo()中的foo()?
据我所读,带有谓词的wait()调用相当于:while (!pred()) { wait(lock); }。谓词在开头为true ( turn的初始值为Turn::FOO),但是等待调用如何获得通知?关于wait(),我看到如下:
原子地解锁锁,阻塞当前正在执行的线程,并将其添加到等待*this的线程列表中。当执行notify_all()或notify_one()时,线程将被解除阻塞。它也可能是伪造的。解除阻塞时,不管原因如何,重新获取锁并等待退出。
但我看不到另一个线程(运行bar()的线程)执行notify_one(),因为turn仍然是FOO。
发布于 2021-07-23 22:09:50
,
foo()内部的cv.wait在开始时是如何触发的?
它将由对true的谓词求值触发。等效循环:
while (!pred()) {
wait(lock);
}甚至一次都不会调用wait() (无论如何,这是第一次访问这一行代码)。
https://stackoverflow.com/questions/68505381
复制相似问题