c++11 线程间同步---利用std::condition_variable实现

1.前言

很多时候,我们在写程序的时候,多多少少会遇到下面种需求

一个产品的大致部分流程,由工厂生产,然后放入仓库,最后由销售员提单卖出去这样。

在实际中,仓库的容量的有限的,也就是说,工厂不能一直生产产品,如果生产太多就会导致仓库满了没地方存放。

为了达到生产效率最大化,就会这样做,只要仓库空了一点位置,工厂就开始生产,等仓库满了以后,工厂就停止生产。

在这过程中,工厂生产产品的速度是销售部卖出产品的速度快很多的。

回到编程中,工厂就是一个单独子线程, 销售部也是一个单独子线程

要想模拟达到上边想要的需求,这就需要用线程间同步啦。

情形1

情形2

情形3

2.准备工作

演示环境 解决方式
vs2017 c++11 条件变量

线程间同步机制,有很多的实现方式,这里采用了条件变量的方式。

c++11 把线程thread添加到了标准库,我们可以很方便的使用多线程和进行移植。

只需要引入thread头文件即可使用。

#include <thread>

此次我们需要用到的头文件

#include <iostream>  
#include <atomic>   
#include <thread>              /*线程类*/          
#include <condition_variable>  /*条件变量*/
#include <mutex>               /*线程锁*/

前提: 在使用 std::condition_variable 时,需要配合 mutex 来使用std::unique_lock进行上锁/解锁。

3.代码演示

#include <iostream>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <mutex>

std::mutex _mutex;                 /*线程锁*/
std::condition_variable cv;		   /*条件变量*/
std::atomic_int  productCnt = 0;   /*公共变量,产品库存数量*/
std::atomic_bool isReady = false;  /*公共变量,防止假性唤醒线程*/

/*生产产品*/
void Fun1()
{
	while (true)
	{
		std::unique_lock<std::mutex> lock(_mutex);

		std::cout << "+++生产了产品, 库存剩余:" << ++productCnt << std::endl;

		isReady = true;   /*产品生产好了*/
		cv.notify_all();  /*唤醒线程,通知Fun2()产品可以卖了*/
		cv.wait(lock);	  /*睡眠线程,Fun1()在等待Fun2()把产品卖出去再生产*/
	}
}

/*销售产品*/
void Fun2()
{
	while (true)
	{
		std::unique_lock<std::mutex> lock(_mutex);

		/*Fun1()产品还没生产好,Fun2()在这睡大觉*/
		if (!isReady) {
			cv.wait(lock);
		}

		std::cout << "---卖出了产品, 库存剩余:" << --productCnt << std::endl;

		isReady = false;/*Fun2()把产品买出去啦*/

		cv.notify_all();/*Fun2()告诉Fun1()产品已经卖了,可以继续生产了*/
	}
}

/*主函数*/
int main(int argc, char **argv)
{
	std::thread t1(Fun1);/*声明线程1*/
	std::thread t2(Fun2);/*声明线程2*/

	t1.join();/*开启线程1*/
	t2.join();/*开启线程2*/

	return 0;
}

调试结果

posted @ 2021-07-08 11:47  想想就很离谱  阅读(452)  评论(3编辑  收藏  举报