操作系统(C++)——生产者消费者模型

2023-05-16

一、C++实现代码

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

using namespace std;

mutex  mymutex;  //定义一个互斥量,即可以理解为一把锁  //防止两个线程同时操作一个内存空间
condition_variable condition;  //定义了一个条件变量,用于线程之间的通信

class Queue {
public:
	void put(int val) //生产物品
	{
		unique_lock<mutex> myunilock(mymutex); //抢占锁,才可以进行执行下面的代码   

		while (!que.empty()) {  //队列不为空,则等待消费者消费
			                            //wait()有两个参数,第二个参数可以为true或false(不写默认为false),若为true,那么wait直接返回并继续执行,若为false,阻塞等待,即下面的作用
			condition.wait(myunilock); //用来等待一个东西:就本例子来说,wait解除互斥锁,并阻塞到本行,知道某个线程调用notify_all成员函数为止
		}
		que.push(val);
		condition.notify_all(); //用于唤醒其他线程,即唤醒消费者线程,进行消费
		cout << "生产了:" << val << " 号产品" << endl;
	}
	int get() {
		unique_lock<mutex> myunilock(mymutex);
		while (que.empty()) { //队列为空,则等待生产者进行生产
			condition.wait(myunilock);
		}
		int val = que.front();
		que.pop();
		condition.notify_all();  //唤醒生产线程,进行生产
		cout << "消费了:" << val << " 号产品" << endl;
		return val;
	}
private:
	queue<int> que;
};
//生产者线程
void producer(Queue* que) {  
	for (int i = 0; i < 10; ++i) {//生产10个产品
		que->put(i);
		this_thread::sleep_for(chrono::milliseconds(100));
	}
}
//消费者线程
void consumer(Queue* que) {  
	for (int i = 0; i < 10; ++i) {
		que->get();
		this_thread::sleep_for(chrono::milliseconds(100));
	}
}
int main() {
	Queue que;  //两个线程共享的队列
	//创建两个线程:生产者和消费者
	thread t1(producer,&que);   
	thread t2(consumer, &que);
	//子线程和主线程汇合
	t1.join();
	t2.join();
	return 0;
}

二、代码流程解释

假设消费者线程,抢占锁成功,生产者获取不到锁,就会阻塞在unique_lock myunilock(mymutex)这行代码处。
消费者先执行 ,判断队列是否为空,发现为空(因为此时还没有生产任何产品),进入while循环,进入等待并释放锁,此时生产线程拿到锁,同样判读队列是否为空,发现为空,不会进入while循环,直接执行生产代码,接着执行condition.notify_all();相当于通知消费者模型,我这边生产出产品了,你可以进行消费,那么消费者就可以退出等待的状态,但是此时并不能执行接下来的消费代码因为此时的消费者线程并没有获取到锁,属于阻塞的状态,当生产者模型的代码完全执行完之后,释放锁,之后消费者获取锁,才能进行消费。若此时生产者线程先与消费者抢占到锁,那么会进入生产者线程,判断队列是否为空,不为空,进入while循环,等待消费者,进入等待并释放锁,接着消费者拿到锁。。。。。重复步骤执行。

学习视频:生产者消费者模型

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

操作系统(C++)——生产者消费者模型 的相关文章

随机推荐

  • 妙用shell脚本画图形

    妙用shell脚本画图形 目录 妙用shell脚本画图形一 99乘法表二 输出1条直线三 画矩形四 左边直角三角形五 右侧直角三角形六 等腰三角形七 平行四边形八 梯形九 菱形 一 99乘法表 展示一 xff1a 展示二 xff1a 二 输
  • 搭建LNMP基础框架

    目录 一 编译安装Nginx服务二 编译安装MySQL服务三 编译安装PHP服务四 部署Discuz xff0c 社区论坛Web应用 一 编译安装Nginx服务 1 关闭防火墙 xff0c 将安装Nginx所需软件包传到 opt目录下 sy
  • 银河麒麟4.0.2二进制安装mysql5.7

    先查看银河麒麟的版本 root 64 idiom kylin1 cat etc kylin build Kylin 4 0 2 Build 20191024 一 下载二进制包 xff0c 并安装所需软件 root 64 idiom kyli
  • 使用shell脚本一键部署LNMP架构

    span class token comment bin bash span span class token comment 将需要的安装包传到 opt目录下 xff0c 并关闭防火墙 span systemctl stop firewa
  • Nginx优化与防盗链

    目录 一 隐藏版本号二 修改用户与组三 缓存时间四 日志分割五 连接超时六 更改进程数七 配置网页压缩八 配置防盗链九 fpm参数优化 一 隐藏版本号 可以使用Fiddler工具抓取数据包 xff0c 查看Nginx版本 也可以在Cento
  • MySQL索引、事务与存储引擎

    目录 一 MySQL索引1 索引的概念2 索引的作用3 创建索引的原则依据4 索引的分类和创建4 1 61 61 普通索引 61 61 4 2 61 61 唯一索引 61 61 4 3 61 61 主键索引 61 61 4 4 61 61
  • openstack基础知识

    目录 一 云计算1 什么是云计算2 云计算的特色3 云计算的三种使用方式1 xff09 公有云2 xff09 私有云3 xff09 混合云 4 云计算服务模型1 xff09 IaaS 基础架构即服务 2 xff09 PaaS xff08 平
  • openstack-keystone

    目录 一 keystone身份服务二 keystone的主要功能三 keystone相关概念四 keystone认证流程五 OpenStack Keystone组件部署步骤部署步骤 一 keystone身份服务 keystone xff08
  • k8s-----------YAML&harbor

    目录 概述使用YAML文件创建资源1 查看资源版本的标签2 创建yaml文件测试 Pod1 特点2 pod容器分类3 镜像拉取策略 部署harbor1 登录harbor私有仓库2 下载Tomcat镜像进行推送3 推送 概述 Kubernet
  • k8s-----------高级pod&调度

    目录 pod进阶pod重启策略 健康检查 探针调度约束调度方式 故障排除 pod进阶 limits cup cpu上限limits memory 内存上限requests cpu 创建时分配的基本CPU资源requests memory 创
  • k8s-----------控制器

    目录 Deployment 部署无状态应用 Pod与控制器之间的关系 SatefulSet xff08 部署有状态应用 xff09 无状态和有状态无状态有状态 常规service和无头服务区别DaemonSetjobCronJob 控制器
  • 安装electron时安装失败解决

    错误描述 xff1a 在安装 electron 的时候 xff0c 使用官方推荐的如下命令 xff1a npm install save dev electron 结果报错如下 npm ERR code 1 npm ERR path D A
  • 10:天干地支

    10 天干地支 时间限制 1 S 内存限制 8192 KB Accept 15 Submit 41 提交 讨论版 描述 天干地支 xff0c 源自中国远古时代对天象的观测 甲 乙 丙 丁 戊 己 庚 辛 壬 癸 称为十天干 xff0c 子
  • txt格式vscode转码

    txt打开异常 xff0c 或乱码 右下角有格式类型 xff1a utf 8 xff0c 点击它会有一个 select action 弹框 可选择特定格式重新打开 xff0c 或保存 选择好对应的格式 乱码解决 或者点击 save with
  • 送给 Java 程序员的 Spring 学习指南

    https www infoq cn article Ad 8ghcGGCNU572U6oEX 学习 Spring 的基础要求 Spring 官网首页是这么介绍自己的 Spring the source for modern Java xf
  • Centos下如果是二进制文件,编辑是文本,后缀是sh也无法执行

    这次部署redis遇到个问题 xff0c 执行sh文件来启动redis xff0c 结果报配置文件无法打开 用vi打开sh文件反复检查过路径是对的 然后手敲路径执行 xff0c 运行正常 xff1b 直接执行sh文件不行 xff1a 反复修
  • Python Pandas 查看数据信息 DataFrame.info()

    在进行数据分析之前 xff0c 需要先查看数据的信息 xff0c 这样才方便后续的数据处理 比如 xff0c 在excel表中20220520是一个常规类型的数据 xff0c 那它导入到DataFrame中是int类型还是str类型呢 xf
  • 03-1.MariaDB安装配置详细步骤

    Author xff1a Sickey Date xff1a 2021 11 25 安装前准备 配置静态IP防火墙等等 1 安装mariadb数据库 先查看RDO中MariaDB的版本及配置 etc my cnf d server cnf
  • 24行代码简单实现qq空间自动点赞

    什么是Auto js xff1f Auto js是基于JavaScript语言运行在Android平台上的工具 它依赖于无障碍服务 它可以做什么 xff1f 解放双手 xff0c 让手机自动打游戏 自动签到 自动领红包等等等等 它有什么优点
  • 操作系统(C++)——生产者消费者模型

    一 C 43 43 实现代码 span class token macro property span class token directive hash span span class token directive keyword i