Ion*_*rel 4 c++ multithreading synchronization c++11
条件变量可用于向其他线程发出已发生事件的信号:
mutex m;
condition_variable cv;
thread t1([&cv]{
// processing
...
cv.notify_one();
});
...
unique_lock<std::mutex> lck(m);
cv.wait(lck);
Run Code Online (Sandbox Code Playgroud)
但正如您所看到的,在我们等待通知之前,有一个完成线程处理并且通知正在经过的机会窗口,因此我们将永远等待.
在这种情况下,一个常见的解决方案是使用标志:
mutex m;
condition_variable cv;
bool done = false;
thread t1([&cv,&done]{
// processing
...
done = true;
cv.notify_one();
});
...
unique_lock<std::mutex> lck(m);
cv.wait(lck, [&done]{return done;});
Run Code Online (Sandbox Code Playgroud)
使用标志的常用方法是使用a condition_variable,还是我的解释错了?
条件变量应始终与某些条件相关联,您应该测试:
unique_lock<mutex> lck(m);
while (!something)
cv.wait(lck);
在保持互斥锁时检查条件,这意味着互斥锁应该保护与条件相关的数据,因此您知道它在测试和等待之间不会改变.
测试while不仅仅是if因为某些条件变量实现(包括基于pthreads的实现)可能是虚假唤醒,即当没有人发出信号时,所以你应该检查循环中的条件并重新等待它不是真的.有一个重载wait需要一个谓词并通过等待谓词返回true来自动处理虚假唤醒,例如,上面的示例被修改为使用检查条件的lambda:
unique_lock<mutex> lck(m);
cv.wait(lck, [&] { return something; });
(在简单的情况下,我发现显式while循环更容易阅读.)
正在使用的条件变量可以被认为是由条件变量,互斥体和谓词组成的3元组,它们通过一起使用来等待条件变量在概念上绑定在一起.特定条件变量对象上的所有并发等待必须使用相同的互斥锁,并且通常也会等待同一个谓词(或依赖于相同数据的相关谓词,受同一个互斥锁保护.)