操作系统_生产者消费者问题

article/2025/11/10 0:40:33

目录

1,生产者消费者问题

问题的提出

初步思考

进程资源共享关系和同步关系分析

问题的具体解决

第一搏 

存在的问题

第二搏

多维度思考

1,单生产者、单消费者、多缓冲区

2,多生产者、多消费者、单缓冲

3,单生产者、单消费者、单缓冲

4,允许生产者写时,消费者可读

5,缓冲池无限大

6,调整生产者wait顺序

7,调整消费者wait顺序

8,调整wait顺序(生产者和消费者)

9,调整signal顺序


生产者消费者问题

问题的提出

  • 多个生产者多个消费者通过共享含n个缓冲区的缓冲池Buffer协作;
  • 其中生产者负责生产数据并投入缓冲池,消费者从缓冲池中取数据消费;
  • 生产者和消费者,每次生产/消费1个数据,要求每个数据必须且只被消费一次
  • 缓冲池为临界资源。请用记录型信号量进行同步。

初步思考

1,生产者可以向未满的缓冲池中放入数据,消费者从非空的缓冲池中取出数据。

2,简化并忽略一些与同步无关的问题:

  • 生产的数据以怎样的顺序放入Buffer?消费者怎样取出(进程何时/怎样被唤醒)?
  • 假设数据按照次序依次放入缓冲区,不需要详细安排;

3,可以想到使用队列来实现数据资源描述,考虑现实中Buffer的实现,为了更充分的利用空间(当队列以数组形式实现时,防止出现假满队列的情况),采用循环队列。生产者生产一个数据,指针in前移,消费者消费一个数据,指针out前移;

进程资源共享关系和同步关系分析

1,思考:

  • 几个进程?:两种进程(生产者,消费者);
  • 共享什么样的资源?:生产者进程共享缓冲区资源;消费者进程共享缓冲区资源;

2,生产者进程一样,故可用一个模板来描述。消费者相同;

问题的具体解决

第一搏 

考虑到有两种临界资源:空/满缓冲区资源,故设计两个资源信号量:full、empty,于是:

如图,可以实现:生产者进程共享空缓冲区资源,消费者共享满缓冲区资源,当资源不足时,可以对相应进程阻塞。

存在的问题

以入队为例,当执行完Buffer(in):=nextp时,时间片耗尽,这时又进来了一个生产者进程,空缓冲区资源足够,于是也到了Buffer(in):=nextp这一步,但由于上一个进程刚给in所指位置赋值,in还没来得及前移,in所指位置就又被新的数据覆盖,从而出现错误。

第二搏

问题存在的原因是:声明的变量in和out,此时也成为了临界资源,所以对入队和出队的操作也需要采取信号量机制,形成临界区

设计互斥信号量:mutex(n.互斥量; 斥体; 互斥; 互斥锁; 互斥对象)

至此问题完美解决,上图就是生产者-消费者问题的标准解答!

多维度思考

1,单生产者、单消费者、多缓冲区

显然资源信号量full和empty,不能省略(省去之后,无法标记缓冲区的状态);

互斥信号量省去,会出现读的同时进行写,或者写的同时进行读;

因此无法简化

2,多生产者、多消费者、单缓冲

此时资源信号量:full和empty初始取值为0,1;

设想运行过程如下:

  1. 开辟消费者进程,但是由于full为0,进入阻塞;
  2. 若仍是消费者进程,仍进入阻塞状态;
  3. 当开辟生产者进程时,empty变为0,在写入数据过程中又有一个生产者进程切换进来,但是此时empty为0,空缓冲资源不足,因此进入阻塞。也就是说此时第一个生产者进程执行完毕释放出full之前,任何生产者/消费者进程都将被阻塞;
  4. 第一个生产者进程释放full后,便唤醒下一个进程。若为生产者进程,则继续阻塞,否则执行消费者进程;
  5. 此后同理

由此可见,这种情况不需要设置互斥信号量mutex,也可实现进程互斥

代码如下:

3,单生产者、单消费者、单缓冲

类似于2的简化版,但是程序仍然同2.

4,允许生产者写时,消费者可读

标准程序中,设置了一个mutex,使得任何时候只有一个生产者或是消费者进程执行;

为了使写时消费者可读,需要设置两个mutex:mutexP和mutexC,使得消费者与消费者进程、生产者与生产者进程之间互斥,而消费者进程与生产者进程可以同时进行。

5,缓冲池无限大

此时缓冲区资源取之不尽,因此,在生产者在写入数据时不需要考虑申请空缓冲区资源wait(empty);

即可以省略共享信号量empty

6,调整生产者wait顺序

如图:

当缓冲池放数据(条件1),empty=0,full=n,又来一个生产者(条件2),在wait(empty)后进入阻塞,此时mutex已被阻塞,那么此后不论来生产者/消费者,都将阻塞,产生死锁!

7,调整消费者wait顺序

情况同6类似。

当缓冲池数据(条件1),empty=n,full=0,又来一个消费者(条件2),在wait(full)后进入阻塞,此时mutex已被阻塞,那么此后不论来生产者/消费者,都将阻塞,产生死锁!

8,调整wait顺序(生产者和消费者)

会出现6,7中的问题。

9,调整signal顺序

当空缓冲资源empty=0时,此时一消费者进程执行完signal(empty),empty=1,若发生了进程切换(消费者行为已经结束),一生产者进程开始执行,但由于mutex未被上一进程释放,因此生产者虽然有空缓冲资源,却无法正常执行,违反了空闲让进的原则。

 

 

 


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

相关文章

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

目录 一.生产者消费者问题(问题描述) 二.问题分析 三.背景知识 四.代码实现 五.实验结论 一.生产者消费者问题(问题描述) 有一个生产者在生产产品,这些产品将提供给一个消费者去消费,为了使生产者和消…

生产者消费者问题

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

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

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

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

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

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

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

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

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

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

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

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

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

MybatisPlus代码自动生成

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

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

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

C语言代码自动生成工具

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

前端代码自动生成器

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

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

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

IDEA自动生成代码插件

官方介绍 基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml)。 只要是与数据库相关的代码都可以通过自定义模板来生成。支持数据库类型与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. 工具都生成了啥呢? 0. 概要 Matlab网站提供了很多…

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

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

Mybatis Plus自动生成代码

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

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

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

Simulink 自动代码生成原理

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

如何自动生成SpringBoot项目代码

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