#include <condition_variable> #include <mutex> #include <future> #include <iostream> #include <thread> #include <queue> using namespace std; queue<int> q; mutex queueMutex; condition_variable queueCondVar; void provider(int val) { for (int i = 0; i < 6; ++i) { { this_thread::sleep_for(chrono::milliseconds(1000)); cout << " Wait "; this_thread::sleep_for(chrono::milliseconds(1000)); lock_guard<mutex> lg(queueMutex); q.push(val + i); } queueCondVar.notify_one(); //this_thread::sleep_for(chrono::milliseconds(val)); } } void consumer(int num) { while (true) { int val; { unique_lock<mutex> ul(queueMutex); queueCondVar.wait(ul, []{return !q.empty(); }); val = q.front(); q.pop(); } cout << "consumer" << num << ":" << val << endl; } } int main() { auto p1 = async(launch::async, provider, 100); auto p2 = async(launch::async, provider, 300); auto p3 = async(launch::async, provider, 500); auto c1 = async(launch::async, consumer, 1); //this_thread::sleep_for(chrono::milliseconds(5000)); auto c2 = async(launch::async, consumer, 2); //system("pause"); p1.get(); p2.get(); p3.get(); c1.get(); c2.get(); return 0; }
在consumer中:我们要使用
unique_lock<mutex> ul(queueMutex);
queueCondVar.wait(ul, []{return !q.empty(); });
因为等待的函数中有可能锁定和解锁mutex.
另外,condition variable也许有所谓的假醒,所以我们使用
[]{return !q.empty(); }来防止假醒对程序的影响。
注意,两个consumer的并发等待被通知次序是不确定的。
还要condition variable也提供给你一个接口允许你等待某个最大时间量:wait_for()用来等待一个时间段,wait_until()用来等待直到某个时间点。