完整代码如下:
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
std::mutex mutex_;
std::condition_variable condVar;
void doTheWork(){
std::cout << "Processing shared data." << std::endl;
}
void waitingForWork(){
std::cout << "Worker: Waiting for work." << std::endl;
std::unique_lock<std::mutex> lck(mutex_);
condVar.wait(lck);
doTheWork();
std::cout << "Work done." << std::endl;
}
void setDataReady(){
std::cout << "Sender: Data is ready." << std::endl;
condVar.notify_one();
}
int main(){
std::thread t1(waitingForWork);
sleep(0.1);
std::thread t2(setDataReady);
t1.join();
t2.join();
}
结论:
1 去掉 sleep(0.1); 会偶尔出现 t1 始终等待的情况。说明condVar.notify_one();先执行了。这是由于多线程运行的顺序不确定造成的。所以 condVar.wait(lck); 可以加 lambda,返回false阻塞,notify_one()再调用一次lambda,如果还是返回false仍然会阻塞。lambda如果直接返回true,则不会阻塞。但是没什么意义。
2 sleep(0.1);放在 t1.join();后面,也会偶尔出现 t1 始终等待的情况。说明 thread 对象一创建,线程就开始运行了。
3 有一个虚假唤醒的概念,当有很多线程等待的时候 condVar.notifyOne()就会出现你不能指定哪一个线程唤醒,需要加变量。所以本示例不存在虚假唤醒。
4 condition_variable类似 windows 事件锁 CreateEvent(), mutex(递归互斥锁) 类似 windows 的临界区。mutex默认对象,同一线程多次lock()也会锁住