C++多线程实战: 实现简单的生产者-消费者模式

2023-05-16

文章目录

  • 前言
  • 1. 生产者/消费者模式介绍
  • 2. 生产者/消费者模式实现
  • 总结


前言

最近在复习C++多线程方面的知识,借此机会实现了生产者-消费者模式。


1. 生产者/消费者模式介绍

本次实现的生产者消费模式,读者可以类比馒头生产和销售。馒头生产最多存储10个大馒头,再多就不新鲜了,哈哈。这里以c++ 容器 deque来保存生产的馒头,详细的过程参考代码实现中的注释即可。

2. 生产者/消费者模式实现

	std::deque<int> deqProducts;//保存生产的商品
	static int PRODUCT_MAX_NUM = 10;//deqProducts中最大商品数量
	bool bTerminate = false;//消费者是否停止买商品, false-可以继续买,true - 停止买商品
	std::mutex mProducer, mConsumer, mPrint;//互斥信号量:生产者,消费者,客户端打印
	std::condition_variable cvProducer, cvConsumer;//条件变量:生产者、消费者
	//生产者生产过程
	auto producer = [&](int i) {
		std::unique_lock<std::mutex> uLock(mProducer);
		while (deqProducts.size() > PRODUCT_MAX_NUM) {
			cvProducer.wait(uLock);//队列已满,等待消费者消费后才能继续生产商品;
		}

		//为客户端打印添加临界区,避免打印乱行
		mPrint.lock();
		std::cout << "Producer will produce product: " << i << std::endl;
		mPrint.unlock();

		deqProducts.push_back(i);//生产产品并保存到列表
		cvConsumer.notify_all();//产品列表不为空,通知消费者可以购买商品了
	};
	//消费者购买商品过程
	auto consumer = [&]() {
		while (true) {//第一层无限循环,无数消费者排队买商品
			std::unique_lock<std::mutex> uLock(mConsumer);
			while (deqProducts.empty() && !bTerminate) {
				cvConsumer.wait(uLock);//商品列表为空且还未停止售卖商品,消费者需要等待生产者生产出商品。
			}
			
			if (bTerminate) {
				break;//已停止售卖商品,遣散还在排队的消费者们
			}
			
			int product = deqProducts.front();
			deqProducts.pop_front();//一个消费者购买了一个商品
			
			//为客户端打印添加临界区,避免打印乱行
			mPrint.lock();
			std::cout << "Consumer already consume product: " << product << std::endl;
			mPrint.unlock();

			cvProducer.notify_all();//消费者已消费一个商品,通知生产者可以继续生产了
		}
	};

	std::vector<std::thread> vecThProducers;//众多的生产者们
	vecThProducers.reserve(PRODUCT_MAX_NUM);//限制最多10个生产者

	std::thread thConsumer = std::thread(consumer);//一个消费者

	for (int i = 0; i < PRODUCT_MAX_NUM; i++) {
		vecThProducers.push_back(std::thread(producer, i + 1));
	}

	std::this_thread::sleep_for(std::chrono::milliseconds(5000));
	bTerminate = true;//商品仅允许售卖5s
	std::cout << "main - bTerminate:" << bTerminate << std::endl;
	cvConsumer.notify_all();//通知消费者时间已到,商品停止售卖

	thConsumer.join();
	for (auto& thProducer : vecThProducers) {
		thProducer.join();
	}

总结

上述实例仅仅用于展示复习的多线程知识点:std::thread, std::mutex, std::condition_variable,希望也能对各位读者有点帮助,如有错误,欢迎指正啊。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++多线程实战: 实现简单的生产者-消费者模式 的相关文章

  • tp6数据库查询结果是个对象而不是数组

    span class token comment 填空题统计 span span class token variable blank nums span span class token operator 61 span span cla
  • ffmpeg通过 av_dict_set 设置参数

    特殊 case xff1a span class token function av dict set span span class token punctuation span span class token operator amp
  • scikit简介

    1 scikit learn示例 1 数据采集和标记 from sklearn import datasets digits 61 datasets load digits 2 特征选择 直观方法 xff0c 直接使用图片的每一个像素点 8
  • 知识图谱技术路线

    知识图谱技术路线 知识图谱知识表示含义分类表示学习 构建模式架构分类 知识建模开放型知识图谱领域知识图谱建模方法 知识抽取结构化数据半结构化数据非 半结构化数据 知识融合方法单图谱跨图谱工具 知识存储RDF三元组水平存储属性存储垂直分割图存
  • 阿里P8大佬亲自讲解!写给程序员的Flutter详细教程,灵魂拷问

    我们程序员经常迷茫于有太多东西要学 xff0c 有些找不到方向 不知所措 很多程序员都愿意说 xff0c 我想变得更好 xff0c 但是更好是什么却很模糊 xff0c 同时我们又不知道该怎么样去做 我们的生命如此短暂 xff0c 作为程序员
  • Linux 环境下验证码无法正常显示,提示 Could not initialize class sun.awt.X11GraphicsEnvironment

    验证码无法正常显示 xff0c 提示 Could not initialize class sun awt X11GraphicsEnvironment 在 Linux 下部署项目时 xff0c 一直遇到一个验证码不显示 xff0c 看了日
  • ubuntu 安装python3.6

    一 运行命令 sudo add apt repository ppa jonathonf python 3 6 可能会出现Ubuntu无法找到add apt repository问题的解决方法 解决办法 xff1a 1 apt get in
  • MTK的android镜像 解包和打包( boot.img, system.img, userdata.img, or recovery.img)

    DESCRIPTION MTK codebase编译出来的image必须使用MTK codebase里的工具才能解开或打包 xff0c 网络上的打包 解包工具不能在MTK的image里使用 KEYWORD 打包 解包 diff pyc pa
  • android 抓完整的log的方式(包括logcat抓所有非内核log)

    log 分为 kernel main events radio 几种log kernel属于 linux内核的log xff0c 通过读取 proc kmsg 或者通过串口来抓取 USB连接手机抓取方式 xff1a adb shell ca
  • 字节4轮面试,3轮都问了RecyclerView

    阿里面试总共4轮 xff0c 其中有3轮面试都问到了RecyclerView的问题 面试的点各不相同 xff0c 有原理 嵌套问题 有缓存实现 xff0c 但是最终都是殊途同归 xff0c 所有的问题都汇集在 如何对RecyclerView
  • 重庆思庄Linux技术分享-创建容器对应的systemd服务并设置其开机自启动失败

    容器已启动 xff0c 服务文件也生成在user文件里 xff0c 运行systemctl user daemmon reload 命令重新加载失败 xff0c 在我退出服务端的时候 xff0c 重新用ssh 进入就解决了 要使用 syst
  • Linux下添加应用程序图标

    为没有快捷方式的程序生成快捷方式图标 以SecureCRT为例 生成 desktop图标 编辑文本文件 xff0c 命名为SecureCRT desktop 内容如下 xff1a Desktop Entry Name 61 SecureCR
  • 如何改变Debian桌面 或者 gnome桌面图标的大小

    要改变Debian桌面图标的size xff0c 我们在图标上点击右键 xff0c 会有一个stretch选项 xff0c 通过这个 xff0c 可以用托拽的方法 xff0c 一个一个来改变图标大小 但这个方法很费劲 xff0c 而且托拽的
  • gradle,gradle/wrapper,build.gradle区别

    1 gradle 跟 maven ant一样是构建工具 2 gradle wrapper Gradle Wrapper是Gradle项目的一部分 引入gradle wrapper xff0c 通过读取配置文件中gradle的版本 xff0c
  • AI一般是用来制作什么的

    AI一般用来制作logo 分页 xff0c 海报等等 面板堆栈的话就是很多功能堆放的位置 一般打印出来的话用cmyk模式 如果是在web端的话用RGB模式 xff0c 因为cmyk模式在你进行存储的过程中颜色可能会丢失 出血值就是在你打印东
  • NetworkX画图:nx.draw_networkx(函数详解)

    NetworkX画图 xff1a nx draw networkx 函数详解 draw networkx span class token punctuation span G span class token punctuation sp
  • 小程序代码构成

    了解项目的基本结构 1 pages xff1a 用来存放所有小程序的页面 2 utils xff1a 用来存放工具性质的模块 xff08 例如 xff1a 格式化事件的自定义模块 xff09 3 app js xff1a 小程序项目的入口文
  • 操作系统笔记

    第一章 xff1a 导论 1 计算机系统 的四个组成成分 xff1a 计算机硬件 操作系统 系统程序和用户 可以大致分为硬件 软件和数据 定义 xff1a 现代通用计算机系统由一个或多个CPU和若干设备控制器通过共同的总线相连而成 xff0
  • 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.2

    HP Socket 是一套通用的高性能 TCP UDP HTTP 通信框架 xff0c 包含服务端组件 客户端组件和 Agent 组件 xff0c 广泛适用于各种不同应用场景的 TCP UDP HTTP 通信系统 xff0c 提供 C C
  • java根据图片的url地址下载图片到本地

    java根据图片的url地址下载图片到本地 已知图片的url地址 xff0c 通过java代码下载到本地 xff0c 直接上代码 package demo import java io ByteArrayOutputStream impor

随机推荐