超详解“生产者消费者问题”【操作系统】

article/2025/11/10 0:45:04

目录

一.生产者消费者问题(问题描述)

二.问题分析

三.背景知识

四.代码实现

五.实验结论


一.生产者消费者问题(问题描述)

有一个生产者在生产产品,这些产品将提供给一个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入缓冲区中,消费者可以从缓冲区中取走产品进行消费,不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装满产品且尚未被取走的缓冲区中投放产品。

二.问题分析

1.只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待;

2.只有缓冲区不为空时,消费者才能从中取出产品,否则必须等待;

3.在一个线程进行生产或消费时,其余线程不能进行生产或消费等操作,即保持线程间旳同步;

4.缓冲区是临界资源,各进程必须互斥的访问;

三.背景知识

本实验在一个进程中执行两个线程,一个是生产者线程,一个是消费者线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。

本实验需要三个信号量:

1.互斥信号量mutex:实现进程对缓冲池的互斥使用。

2.信号量Empty:表示缓冲池中空缓冲区的数量。

3.信号量Full:表示缓冲池中满缓冲区的数量。

四.代码实现

生产者线程:

void producer(int index)
{int n = 0;std::unique_lock<std::mutex> lock(mtx);  //unique_ptr获取互斥锁,类似于智能指针的智能锁for (int i = 0; i < 100; i++){while (q.Full())//如果缓冲区满了,生产者线程应该进入等待状态,并且把mtx互斥锁释放掉{cv.wait(lock);}q.Push(n);  //缓冲区不满时,可以生产产品放入缓冲区cout << "生产者生产:" << n << "号物品" << endl;n++;cv.notify_all();//通知其他所有的线程,其他线程得到该通知,就会从 等待状态 变成 阻塞状态 获取互斥锁后才能继续执行}
}

消费者线程:

void consumer(int index)
{std::unique_lock<std::mutex> lock(mtx);for (int i = 0; i < 100; i++){while (q.Empty())//如果缓冲区为空,消费者线程应该进入等待状态,并且把mtx互斥锁释放掉{cv.wait(lock);}int v = 0;q.Pop(v);//如果缓冲区不为空,消费者可以消费缓冲区中的产品cout << "消费者消费:" << v << "号物品" << endl;cv.notify_all();}
}

完整代码:

#include<iostream>
#include <mutex>
#include <condition_variable>//条件变量的头文件
#include <thread>
using namespace std;std::mutex mtx;  //定义互斥锁,做线程间的互斥操作
std::condition_variable cv;  //定义条件变量,做线程间的同步通信操作class Queue
{
public:Queue(){data = NULL;front = 0;rear = 0;size = 0;maxsize = 10;//缓冲区的最大空间为10data = new int[maxsize];}~Queue(){if (data != NULL){delete[] data;data = NULL;}}void Push(const int& v)     //生产产品{data[rear] = v;rear = (rear + 1) % maxsize;size =size+1;}void Pop(int& v)  //消费产品{v = data[front];front = (front + 1) % maxsize;size=size-1;}int Size() const //缓冲区中现有元素个数{ return size;}bool Empty() const //判断现在缓冲区是否为空{if (Size() == 0){return true;}else{return false;}}  bool Full() const//判断现在缓冲区是否为满{if (Size() == maxsize){return true;}else{return false;}}private:int* data;   //指针指向循环队列连续空间int front;  //指向队头指针int rear;  //指向队尾指针int size;  //当前缓冲区中元素个数int maxsize;  //缓冲区的最大容纳空间
};Queue q;
void producer(int index)
{int n = 0;std::unique_lock<std::mutex> lock(mtx);  //unique_ptr获取互斥锁,类似于智能指针的智能锁for (int i = 0; i < 100; i++){while (q.Full())//如果缓冲区满了,生产者线程应该进入等待状态,并且把mtx互斥锁释放掉{cv.wait(lock);}q.Push(n);  //缓冲区不满时,可以生产产品放入缓冲区cout << "生产者生产:" << n << "号物品" << endl;n++;cv.notify_all();//通知其他所有的线程,其他线程得到该通知,就会从 等待状态 变成 阻塞状态 获取互斥锁后才能继续执行}
}void consumer(int index)
{std::unique_lock<std::mutex> lock(mtx);for (int i = 0; i < 100; i++){while (q.Empty())//如果缓冲区为空,消费者线程应该进入等待状态,并且把mtx互斥锁释放掉{cv.wait(lock);}int v = 0;q.Pop(v);//如果缓冲区不为空,消费者可以消费缓冲区中的产品cout << "消费者消费:" << v << "号物品" << endl;cv.notify_all();}
}int main(){std::thread t1(producer, 1);  //生产者线程std::thread t2(consumer, 2);  //消费者线程t1.join();t2.join();return 0;
}

部分运行结果展示:

 

五.实验结论

生产者消费者问题是一个经典的同步问题,通过本次实验我学到了线程同步问题以及信号量机制的使用,加深了我对操作系统多线程机制的理解和认识,同时也掌握了一些C++语言编程语言相关知识。


http://chatgpt.dhexx.cn/article/OAVC3dxd.shtml

相关文章

生产者消费者问题

文章目录 1.生产者消费者问题1.1 问题描述1.2 问题分析1.3 如何实现1.4 思考① -> ② -> ③③ -> ④ -> ① 1.5 小结 2.多生产者 - 多消费者2.1 问题描述2.2 问题分析2.3 如何实现2.4 小结 1.生产者消费者问题 1.1 问题描述 系统中有一组生产者进程和一组消费者进…

《操作系统》-生产者消费者问题

什么是生产者消费者问题&#xff1f; 系统中有一组生产者进程和一组消费者进程。生产者进程每次生产一个产品放入缓冲区&#xff0c;消费者进程每次从缓冲区中取出一个进程并使用&#xff0c;那么他们之间具有这样一层关系 生产者、消费者共享一个初始为空、大小为n的缓冲区。…

生产者-消费者问题(操作系统)

生产者-消费者问题从特殊到一般(从易到难)可以分3种形式&#xff1a; 一个生产者、一个消费者、一个缓冲区的问题&#xff1b; 一个生产者、一个消费者、n个缓冲区的问题&#xff1b; k个生产者、m个消费者、n个缓冲区的问题&#xff1b; ★当缓冲区空时&#xff0c;生产者可…

Java多线程——生产者消费者问题

创建多个线程去执行不同的任务&#xff0c;如果这些任务之间有着某种关系&#xff0c;那么线程之间必须能够通信来协调完成工作。 生产者消费者问题&#xff08;英语&#xff1a;Producer-consumer problem&#xff09;就是典型的多线程同步案例&#xff0c;它也被称为有限缓冲…

生产者-消费者问题(详解)

目录 1.问题描述 2.问题分析 3.问题实现 3.1 初始化 3.2 生产者 3.3 消费者 1.问题描述 要求如下&#xff1a; 只要缓冲区没满&#xff0c;生产者才能把产品放入缓冲区&#xff0c;否则必须等待。只有缓冲区不空时&#xff0c;消费者才能从中取出产品&#xff0c;否则必…

【操作系统】生产者消费者问题

生产者消费者模型 文章目录 生产者消费者模型 [toc]一、 生产者消费者问题二、 问题分析三、 伪代码实现四、代码实现&#xff08;C&#xff09;五、 互斥锁与条件变量的使用比较 一、 生产者消费者问题 生产者消费者问题&#xff08;英语&#xff1a;Producer-consumer proble…

Sublime Text实现代码自动生成,快速编写HTML/CSS代码

目录 下载Sublime Text安装emmet插件常用自动生成HTML代码实例初始化页面自动补全标签配对自动添加类名和id名自动填充文本内容自动生成同级标签自动生成嵌套标签自动生成提级标签自动生成分组标签自动生成多个元素自动生成带多个属性的元素自动生成隐式标签 常用自动生成CSS代…

MybatisPlus代码自动生成

这里写自定义目录标题 前言一. 什么是 MyBatis-Plus二.MybatisPlus 代码自动生成①idea 插件生成1. 插件2.连接数据源3.生成代码 ②配置工具类生成 前言 最开始&#xff0c;要在 Java 中使用数据库时&#xff0c;需要使用 JDBC&#xff0c;创建 Connection、ResultSet 等&…

Simulink自动代码生成:生成代码的基本设置

Simulink自动代码生成也被称作基于模型开发&#xff08;BMD&#xff09;&#xff0c;相比于传统的手写代码方式能够尽量减少人为错误。模型本身可以用于仿真&#xff0c;单元测试等&#xff0c;更便于提前发现逻辑错误。同时只要约定好模型接口&#xff0c;就可以多人协作&…

C语言代码自动生成工具

一、模型建模模块&#xff1a; 基于开源开发平台Eclipse&#xff0c;以图形方式创建和编辑模型元素&#xff0c;模型元素如下&#xff1a; 活动&#xff1a;初始活动、简单活动、复杂活动、结束活动&#xff1b;状态&#xff1a;初始状态、状态、结束状态&#xff1b;变迁&a…

前端代码自动生成器

场景 1.CodeFun是什么 CodeFun是一款UI 设计稿智能生成源代码的工具,支持微信小程序端、移动端H5和混合APP,上传 Sketch、PSD等形式的设计稿&#xff0c;通过智能化技术一键生成可维护的前端代码. 2.学习成本高吗&#xff1f; 对于前端工程师来说&#xff0c;几乎没有学习成本…

MATLAB/Simulink自动代码生成(一)

Simulink自带了种类繁多、功能强大的模块库&#xff0c;在基于模型设计的开发流程下&#xff0c;Simulink不仅通过仿真可以进行早期设计的验证&#xff0c;还可以生成C/C、PLC等代码直接应用于PC、MCU、DSP等平台。在嵌入式软件开发中发挥着重要的作用&#xff0c;本文以Simuli…

IDEA自动生成代码插件

官方介绍 基于IntelliJ IDEA开发的代码生成插件&#xff0c;支持自定义任意模板&#xff08;Java&#xff0c;html&#xff0c;js&#xff0c;xml&#xff09;。 只要是与数据库相关的代码都可以通过自定义模板来生成。支持数据库类型与java类型映射关系配置。 支持同时生成生…

Matlab/Simulink自动生成C代码实验

目录 0. 概要 1. Matlab /Simulink/Embedded Coder关系与区别 2. 搭建Simulink模型及仿真 2.1 搭建模型 2.2 仿真 3. 生成代码 3.1 求解器设置为定步长 3.2 安装 MinGW-w64 编译器 3.3 调出Simulink Coder 4. 工具都生成了啥呢&#xff1f; 0. 概要 Matlab网站提供了很多…

关于RuoYi自动代码生成功能的使用

为什么要使用代码生成&#xff1f; 答&#xff1a;因为在后端构建的过程中会有许多重复的类似的代码编写&#xff0c;而我们如果一个个去编写&#xff0c;会耗费大量时间与精力&#xff0c;所以我们可以设计一个功能去自动生成这些重复的&#xff0c;简单的代码。而若依系统就…

Mybatis Plus自动生成代码

mybatis-plus自动生成代码 一、简易生成代码二、指定生成的样式&#xff0c;并且不在一个模块1.父pom文件配置2.子模块pom文件配置3.准备vm文件4.设置MyBatisPlusGenerator.java5.运行MyBatisPlusGenerator.java文件6.运行sign-auth模块,解决异常 一、简易生成代码 /*** 代码生…

Simulink自动代码生成:数据类型别名自定义

在手写代码时&#xff0c;我们经常能看到自定义数据类型别名&#xff0c;例如有些代码中将计算机默认的数据类型改为我们自己习惯的名称&#xff0c;如图所示。 目录 一. 系统默认生成的别名二. 建立Simulink AliasType三. 修改Data Type Replacement四. 数据类型别名修改后的…

Simulink 自动代码生成原理

如下图&#xff0c;Simulink模型会先变成一个文本式的 .rtw 模型描述文件&#xff0c;然后再变成 .c,.h&#xff0c;最后编译为最终目标文件。 典型的 Simulink 用户通常都是&#xff0c;用Simulink设计好算法后&#xff0c;做到生成源代码这一步。然后把生成的算法的.c .h 源代…

如何自动生成SpringBoot项目代码

目录 1.RuoYi源码下载及启动若依服务1.1. RuoYi源码下载1.2. 启动若依服务 2.自动生成代码3.代码及sql文件链接 已经工作一段时间啦&#xff01;首先是从后端开发开始入手的&#xff0c;前端也是在自学阶段&#xff08;边学边问我身边的同事大佬&#xff09;&#xff0c;努力是…

Simulink自动代码生成:数据字典的建立及代码优化

在上一节《Simulink自动代码生成&#xff1a;生成代码的基本设置》的基础上&#xff0c;我们来对模型进行优化&#xff0c;使得生成的代码更能满足实际的需求&#xff0c;没看过我上一篇文章的可以点开如下链接&#xff1a;   Simulink自动代码生成&#xff1a;生成代码的基本…