参考:https://www.cnblogs.com/bigben0123/p/3753148.html
条件变量(Condition Variable)的一般用法是:线程 A 等待某个条件并挂起,直到线程 B 设置了这个条件,并通知条件变量,然后线程 A 被唤醒。经典的「生产者-消费者」问题就可以用条件变量来解决。
这里等待的线程可以是多个,通知线程可以选择一次通知一个(notify_one
)或一次通知所有(notify_all
)。
通过条件变量和互斥锁模拟生产者消费者问题。
//
// main.cpp
// 条件变量
//
// Created by 蓝猫 on 2019/1/3.
// Copyright © 2019年 蓝猫. All rights reserved.
//
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
template <typename T>
class Pro_Consumer
{
private:
int max;//缓冲区最大容量 设置3
std::queue<T> cache;//缓冲区
std::mutex mutex_t;//互斥锁
std::condition_variable cond_pro;// 生产者条件变量
std::condition_variable cond_con; // 消费者条件变量
//bool notfull;//不满 还可以生产
//bool notempty;// 不空 可以消费
bool stop_consume;
public:
Pro_Consumer();
void producer(T &x);
bool consumer();
void Main();
};
template <typename T>
void Pro_Consumer<T>::Main()
{
std::thread pro([&]()
{
for(int i=1;i<=10;i++)
{
producer(i);
}
}
);
std::thread consu([&]()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
while (stop_consume==false)
{
stop_consume=consumer();
}
}
);
pro.join();
consu.join();
}
template <typename T>
Pro_Consumer<T>::Pro_Consumer()
{
max=3;
//notfull=true;
//notempty=false;
stop_consume=false;
};
template <typename T>
void Pro_Consumer<T>::producer(T &x)// 生产
{
std::unique_lock<std::mutex> lock(mutex_t);//加锁
while (cache.size()==max)//缓冲区满了 生产者线程等待
{
cond_pro.wait(lock);
}
cache.push(x);
//notempty=true;//生产了就不是空
std::cout<<"生产者生产了:"<<x<<" "<<"队列大小:"<<cache.size()<<std::endl;
cond_con.notify_one();//唤醒消费者
};
template <typename T>
bool Pro_Consumer<T>::consumer()// 消费者
{
//std::cout<<"消费者"<<std::endl;
std::unique_lock<std::mutex> lock(mutex_t);//加锁
while (cache.empty())//缓冲区空了 消费者线程等待
{
cond_con.wait(lock);
}
if(cache.empty()!=true)
{
T temp=cache.front();
cache.pop();
std::cout<<"消费者消费了:"<<temp<<" "<<"队列大小:"<<cache.size()<<std::endl;
if(temp==10)return true;//结束
}
cond_pro.notify_one();//唤醒生产者
return false;
}
int main()
{
Pro_Consumer<int> obj;
obj.Main();
return 0;
}