在此代码中如何通过通知调用 wait() 调用?
How does the wait() call get invoked with notify in this code?
我有如下的 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()
里面的cv.wait(lock, [] {return turn == Turn::FOO; });
一开始是怎么触发的?
根据我的阅读,使用谓词的 wait()
调用等同于:while (!pred()) { wait(lock); }
。谓词一开始就为真(turn
的初始值为Turn::FOO
),但是wait调用如何得到notify呢?关于wait()
,我是这样看的:
以原子方式解锁锁,阻塞当前执行的线程,并将其添加到等待*this 的线程列表中。当执行 notify_all() 或 notify_one() 时,线程将被解除阻塞。它也可能被虚假地解锁。当解除阻塞时,无论什么原因,重新获取锁并等待退出。
但我没有看到其他线程(运行 bar()
)执行 notify_one()
因为 turn
仍然是 FOO
.
How would the cv.wait inside the foo()
get triggered in the beginning?
它将由评估为 true
的谓词触发。等效循环:
while (!pred()) {
wait(lock);
}
不会调用 wait()
一次(反正是第一次访问该行代码)。
我有如下的 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()
里面的cv.wait(lock, [] {return turn == Turn::FOO; });
一开始是怎么触发的?
根据我的阅读,使用谓词的 wait()
调用等同于:while (!pred()) { wait(lock); }
。谓词一开始就为真(turn
的初始值为Turn::FOO
),但是wait调用如何得到notify呢?关于wait()
,我是这样看的:
以原子方式解锁锁,阻塞当前执行的线程,并将其添加到等待*this 的线程列表中。当执行 notify_all() 或 notify_one() 时,线程将被解除阻塞。它也可能被虚假地解锁。当解除阻塞时,无论什么原因,重新获取锁并等待退出。
但我没有看到其他线程(运行 bar()
)执行 notify_one()
因为 turn
仍然是 FOO
.
How would the cv.wait inside the
foo()
get triggered in the beginning?
它将由评估为 true
的谓词触发。等效循环:
while (!pred()) {
wait(lock);
}
不会调用 wait()
一次(反正是第一次访问该行代码)。