1. 条件变量
多线程编程中,等待由另一个线程触发一个时间的最基本机制是条件变量。从概念上说,条件变量与某些事件或其他条件相关,而且一个或多个线程可以等待该条件被满足。当某个线程已经确定条件得到满足,它就可以通知一个或多个正在条件变量上进行等待的线程,以便唤醒它们并让它们继续处理。
#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