在示例代码condition variable中,它显示:
worker
线程拥有互斥锁(唯一锁定),然后等待。
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return ready;});
main
线程仍然可以获得互斥锁(锁定保护)。
{
std::lock_guard<std::mutex> lk(m);
ready = true;
}
这是否意味着lock_guard可以拥有由unique_lock拥有的互斥锁?
答案 0 :(得分:2)
不,这意味着在wait
期间,互斥锁被解锁以允许提供程序线程锁定它并拥有对cv的权限。您省略了您引用的示例代码中最重要的一行,notify_one
:
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one(); // wake up the waiting thread
这就是为什么你需要向wait
提供锁定的原因,因此它可以在睡眠前解锁它并在它醒来后尝试重新锁定它。
从您关联的页面的第一部分开始,尤其是注释2和3:
任何打算在std :: condition_variable上等待的线程都必须
- 在与保护共享变量相同的互斥锁
上获取std :: unique_lock- 执行wait,wait_for或wait_until。等待操作以原子方式释放互斥锁并暂停执行该线程。
- 当通知条件变量,超时到期或发生虚假唤醒时,线程被唤醒,并且原子重新获取互斥锁。然后线程应该检查条件并在唤醒是假的时候继续等待。
醇>