在线程 A 等待条件变量之前的期间,它必须持有一个互斥锁。最简单的解决方案是确保线程 B 在调用 notify_all 时持有相同的互斥锁。所以是这样的:
std::mutex m;
std::condition_variable cv;
int the_condition = 0;
Thread A: {
std::unique_lock<std::mutex> lock(m);
do something
while (the_condition == 0) {
cv.wait(lock);
}
now the_condition != 0 and thread A has the mutex
do something else
} // releases the mutex;
Thread B: {
std::unique_lock<std::mutex> lock(m);
do something that makes the_condition != 0
cv.notify_all();
} // releases the mutex
这保证了线程 B 仅在线程 A 获取互斥体之前或在线程 A 等待条件变量时执行 notify_all()。
不过,这里的另一个关键是等待 the_condition 变为 true 的 while 循环。一旦 A 拥有了互斥锁,任何其他线程都不应该更改 the_condition,直到 A 测试了 the_condition,发现它为假,并开始等待(从而释放互斥锁)。
关键是:您真正在等待的是 the_condition 的值变为非零, std::condition_variable::notify_all 只是告诉您线程 B 认为线程 A 应该唤醒并重新测试。