多线程编程中,等待由另外一个线程触发一个时间的最基本机制是条件变量。从概念上说,条件变量与某些事件或其余条件相关,并且一个或多个线程能够等待该条件被知足。当某个线程已经肯定条件获得知足,它就能够通知一个或多个正在条件变量上进行等待的线程,以便唤醒它们并让它们继续处理。ios
#pragma once #pragma execution_character_set("utf-8") #include <iostream> #include <chrono> #include <ctime> #include <iomanip> #include <string> #include <thread> #include <mutex> #include <condition_variable> #include <list> using namespace std; //下面的例子,一个条件变量值用于控制两个线程运行的前后顺序。 //getData线程wait中先阻塞条件变量,等到putData线程中发送通知时,wait解除阻塞,向下运行。 std::mutex mut; std::condition_variable data_cond; std::list<int> data_list; const int g_count = 11; void putData() { for (int i = 0; i < g_count; ++i) { std::this_thread::sleep_for(std::chrono::seconds(2)); int data = i * 1000; std::lock_guard<std::mutex> lk(mut); //添加数据 data_list.push_back(data); cout << "putData():" << data << endl; data_cond.notify_all(); } } void getData(const string threadName) { while (true) { std::unique_lock<std::mutex> lk(mut); //更直接与直观的写法(当while条件为true时阻塞) while (data_list.empty()) { data_cond.wait(lk); } //wait中的第二个表达式参数返回true时,解除阻塞。 // data_cond.wait( // lk, [](){ return !data_list.empty(); }); int data = data_list.front(); data_list.pop_front(); lk.unlock(); //处理数据 cout << threadName << " getData():" << data << endl; if (data > 10000) { break; } } } int main() { thread t1(putData); thread t2(getData, "Rock"); t1.join(); t2.join(); return 0; }
运行结果以下:编程
putData():0 Rock getData():0 putData():1000 Rock getData():1000 putData():2000 Rock getData():2000 putData():3000 Rock getData():3000 putData():4000 Rock getData():4000 putData():5000 Rock getData():5000 putData():6000 Rock getData():6000 putData():7000 Rock getData():7000 putData():8000 Rock getData():8000 putData():9000 Rock getData():9000 putData():10000 Rock getData():10000