CHS_08.2.3.6_1+生产者-消费者问题

CHS_08.2.3.6_1+生产者-消费者问题

  • 问题描述
  • 问题分析
  • 思考:能否改变相邻P、V操作的顺序?
  • 知识回顾

在这个小节中 我们会学习一个经典的进程同步互斥的问题

问题描述

在这里插入图片描述

并且尝试用上个小节学习的p v操作 也就是信号量机制来解决这个生产者消费者问题

问题的描述是这样的 在一个系统当中 有一组生产者进程和一组消费者进程

生产者进程每次生产一个产品并且放入缓冲区 那这缓冲区其实就是用来存放数据的

一片区域 我们可以把它理解为 一个一个小格子 每个缓冲区 也就是每一个小格子里面可以放一个产品

一个 也就是一坨数据 然后消费者呢 又会从这些缓冲区当中每次取出一个产品 也就是每次

取出一头数据 那生产者和消费者这两组进程他们会共享的使用

一个初始为空 大小为n的缓冲区 也就是有n个小格子可以放n个产品

那需要注意的是 这个缓冲区是有容量限制的 它只能放五个产品

那只有缓冲区没有满的时候 生产者才可以往这个缓冲区里放入产品

比如说像这个样子 因为缓冲区大小为五所以它最多只能放入五个产品 也就五个数据

那如果缓冲区此时已经满了 但是生产者进程还想尝试往里面写数据

那生产者进程必须阻塞等待 等这个缓冲区被取空的时候 他才可以往里边

写数据那有没有发现这个条件 就是我们上小节分析的同步问题

问题分析

在这里插入图片描述

也就是说 缓冲区没满的时候
生产者才能生产 这是一对一前一后的同步关系
另外呢

消费者进程 他会从这个缓冲区里取走这些产品 就是取走这些数据 就像这个样子

那当缓冲区没满的时候 也就是有空闲的缓冲区的时候 生产者就可以继续生产

也就是说 当一个消费者从缓冲区取走数据之后 如果此时有生产者是处于阻塞状态的 那么消费者进程应该把生产者进程给唤醒

让他重新回到就绪态 不过呢 生产者进程只是回到了就绪态 这并不意味着生产者进程会立即往里边写数据

所以接下来有可能是消费者进程继续往把这些缓冲区里的数据依次取走 那需要注意的是 只有缓冲区不空的时候 也就是说只有缓冲区里有数据 有产品的时候
消费者进程才可以从缓冲区里取走数据
不然的话消费者进程就必须阻塞等待

所以其实这个条件就是第二对的同步关系 也就是只有缓冲区没空的时候 或者说缓冲区里有产品的时候

消费者才可以取走数据 才可以消费 那最后一个条件是这个缓冲区 它是一种临界资源

各个进程必须互斥的访问缓冲区 那这我们来解释一下为什么必须互斥的访问缓冲区

那假设这个系统当中此时有两个生产者进程正在并发的运行 那么第一个生产者进程在检查缓冲区的时候发现 哎 这个缓冲区此时都是空的

所以我可以挑选其中的某一片往里面写入数据 与此同时 第二个生产者进程 它也并发的运行

他也发现此时这个缓冲区都是空的 因此他也会挑选其中的一块写入数据

那假设下面的这个生产者进程往这写了一篇数据 而上面这个生产者进程他自己挑选的也是这一片区域
那接下来这个生产者进程也往这片区域冲入自己的数据 那这样的话 他就会把前面那个进程的数据给覆盖掉

所以可以看到 如果各个进程同时访问缓冲区的话 那么有可能会出现一系列的问题 比如说刚才我们提到的数据覆盖
所以缓冲区这种资源 它是一种临界资源 各个进程必须互斥的访问

那么既然需要互斥的访问 这其实就是我们之前学过的互斥的问题 那刚才我们做的这一系列分析

找出了这个问题里边所隐含的一系列的同步和互斥的关系

那第二步我们需要做的是要根据各个进程操作的流程来确定pv操作的大致顺序

那其实很简单 就是我们上个小节中提到过的 前V后P 第一对关系是只有 当
缓冲区里有产品的时候 消费者进程 它才可以消费
另外呢 只有缓冲区没满的时候
生产者进程才可以生产
所以这样的两对一前一后的同步关系 我们就需要给他们分别设置一个同步信号量
在这里插入图片描述

并且在前面这个动作完成之后 需要对这个同步信号量执行一个V操作

在后面这个动作开始之前 需要对这个同步信号量执行一个p操作 那我们一会来解释一下这两个同步信号量 它在背后的含义

那这是这两对同步关系里边pv操作的一个大致顺序 那缓冲区里有产品

这个事件是生产者进程触发的 也就说 当一个生产者进程往缓冲区里放入一个产品 放入一个数据之后
他就需要对这个信号量执行一个V操作
而当消费者进程从缓冲区里取走数据之前
它需要对这个型号量执行一个p操作
那下面的这个同步关系也一样 那除了这两对同步关系之外 我们还需要实现对缓冲区这种临界资源的互斥访问

互斥的实现其实是很简单的 我们只需要设置一个互斥信号量 mutex 并且让它的初始值为一

然后在临界区的前面和后面分别对互斥信号量执行p v操作就可以了 那接下来我们应该做的就是要确定这些信号量的初始值

对于互斥信号量来说 一般初始值就是一就像我们刚才所说的那样 而对于同步信号量来说 它的初始值 我们要看它所对应的那种资源初始值是多少

那我们来看一下这两对同步关系所对应的这种资源到底是什么呢 那先来看上面这对同步关系

消费者进程 他在消费之前需要消耗什么资源呢 需要消耗的是产品 对吧

所以他的这个p操作其实是在申请一个产品 申请一个数据

因此 full这个同步信号量 它所对应的资源应该是产品的数量

也就是非空缓冲区的数量 而从题目当中给的条件 我们知道缓冲区刚开始都是空的

也就是说 刚开始产品的数量 产品这种资源的数量应该是零因此

full这个同步信号量的初始值 我们就把它设置为零表示刚开始没有产品这种资源
而这种资源只能由生产者进程
生产了之后来释放 那再来看第二个同步信号量empty

那我们知道 生产者进程每生产一个产品 就需要消耗一个空闲的缓冲区

因此 empty这个同步信号量 它所对应的资源就应该是空闲缓冲区这种资源

它的数量就是空闲缓冲区的数量 当一个消费者进程取走了产品 也就是

做了消费的动作之后 他就可以释放一个empty 也就是释放一个空闲的缓冲区

那从题目给的条件 我们知道 刚开始缓冲区都是空的 有n个缓冲区 因此空闲缓冲区它的初始值应该是n

所以这样我们就确定了这两个同步信号量的一个初始值 那接下来就是代码的实现

生产者进程 他要做的事情就是不断的生产一个产品 并且把产品放到缓冲区
在这里插入图片描述

而消费者进程 他要做的事情就是不断的从缓冲区里取走一个产品 并且使用这个产品消费这个产品

那通过刚才的分析 我们知道 生产者进程再把产品放入缓冲区之前需要申请一个空闲的缓冲区
因此 当他放入产品之前 需要对empty这个同步信号量执行一个p操作

而当他把产品放入缓冲区之后 其实就相当于产品这一种

资源的数量加一了 或者说非空缓冲区的数量加一了 因此当它放入产品之后 需要对这个信号量执行一个V操作

表示 增加一个这种资源 而消费者进程的分析也类似当他从缓冲区取走一个产品之前
需要先对这个full变量进行一个p操作 也就是要申请消耗一个产品这种资源

而当他取走了一个产品之后 空闲缓冲区的数量就会加一因此在这个操作之后 需要对empty进行一个v操作 表示要增加一个空闲缓冲区

那这样我们就实现了两对同步关系 另外 题目中要求缓冲区必须互斥的访问 它是临界资源 所以在访问缓冲区

前后分别要对这个互斥信号量执行p和v操作 用于实现对缓冲区的互斥访问

那从这个例子当中 我们可以看到 实现互斥的p v操作 它是在同一个进程内进行的

这个进程对临界区上了锁 而当他访问完临界区之后 又需要的对这个临界区进行解锁

所以 这个pv操作是在同一个进程的代码当中实现的 而同步关系就不一样了 我们会发现

这个进程 生产者进程里边是对full变量执行了v操作 而消费者进程里边是对full变量执行了p操作

也就是对同一个变量的p v 这两个操作是分别需要在不同的两个进程之间执行的

执行v操作的这个进程会唤醒相对应的执行p操作的这个进程

那如果结合刚才我们给的这个同步关系的前驱图 就会发现

这个代码其实完全可以根据这个前驱图的关系来得出 那这大家可以自己暂停来

体会一下前V后P 那接下来我们要思考的一个问题是

能否改变相邻的pv操作的顺序呢 也就说我们刚才是先对同步信号量执行了p

思考:能否改变相邻P、V操作的顺序?

在这里插入图片描述

再对互斥信号量执行了p 而我们现在尝试把它颠倒一下 先对这个互斥信号量执行p操作 再对同步信号量执行p操作 会发生什么情况呢

我们来看一下 假设此时这个缓冲区里边已经放满了产品 也就是empty等于零

full等于n 那此时如果生产者进程执行了一使empty的值变为了零

接着 他在执行二这一句 而此时由于empty的值已经是零了 所以生产者进程会被阻塞在二这一句 他需要等待empty这种资源

那这个时候发生了调度消费者进程 上处理机运行 那消费者进程在执行三这一句的时候

他会发现此时empty的值已经是零了 所以消费者进程他会被阻塞在三这一句

他需要等待生产者进程释放mutex 所以这就导致消费者进程也被阻塞了

那我们在捋一捋这种情况下 生产者进程 他在等待消费者进程对empty执行v操作

而消费者进程 他又在等待生产者进程对mutex执行v操作

也就说 他们在相互等待对方唤醒自己 而两个人其实都被阻塞 都在睡眠

而那这种情况就是我们之后会学习到的死锁 进程和进程之间发生了循环等待

被对方唤醒这样的一个神奇的情况 那发生了死锁之后 这两个进程就都不能往下执行 都不能推进下去了

那同样的 大家可以分析一下 当full等于零当empty等于n的时候 如果按341这样的顺序执行 是不是也会发生死锁

所以在这个地方 我们要强调的是实现互斥的这个p操作

一定要在实现同步的p操作之后 他们的顺序是不能颠倒的 如果颠倒的话 那么就有可能出现我们这所提到的死锁的问题

所以这是大家需要特别特别注意的地方 那接下来我们再思考一下 如果V操作的这个顺序颠倒的话 会不会出现问题呢

其实是不会的 因为V操作并不会导致任何一个进程阻塞 所以他们俩的顺序颠倒并不会发生这种循环等待的问题 所以两个V操作的顺序是可以交换的

那最后我们再来考虑一个问题 生产者生产一个产品和消费者使用一个产品 是否可以放到pv操作之间呢

其实逻辑上看是可以放到p v操作这里边的 但是如果我们把这两部分的处理都放到p v操作里边的话

那么就会导致临界区代码变得更长 也就是说 一个进程对临界区上锁的时间会增长
那这样的话 肯定不利于各个进程交替的来使用这个临界区资源

所以我们要让临界区的代码尽可能的短 因此逻辑上来看 把这两个部分放进去是没有问题的

但是实际上会对系统的效能产生影响 因此并不建议把这两个部分的操作放到p为操作里面

好的 那么这个小节当中 我们介绍了一个很经典的进程的同步互斥问题 就是生产者消费者模型

那我们根据这个问题 给出了做pv操作相关题目的一个解题思路 这个解题思路我们会在之后的

那些问题讲解当中在继续应用那生产者 消费者问题 它是一个互斥和同步的综合问题 既包含了互斥又包含了同步

但是对于我们初学者来说 比较困难的是 要发现这个题目当中隐含的两对同步关系

有时候是生产者进程在等待消费者进程 有的时候又是消费者进程需要等待生产者进程

所以这是这个题目当中的难点 它是两对不同的 一前一后的这种关系

所以我们相应的也需要给他们设置两对不同的信号量 但是对这些信号量的操作肯定都是遵循一个前V后P的 这个

原则那根据上个小节的讲解 相信这个地方已经不难理解了 另外还需要再强调一遍的是

知识回顾

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现互斥和实现同步是两个不同的p操作而实现互斥的

那个p操作一定要在实现同步的p操作之后 否则会导致死锁的问题

这个大家在暂停回忆一下 那么在接下来的讲解当中 我们会适当的加快一点点速度 我们不会在像之前一样每个同步信号量都来分析他背后的含义 这个需要大家自己去练习和体会

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大力说视频号第三课:视频小店

自从腾讯推出视频号之后,大家非常明显的感觉到,视频号正以势不可挡的姿势走向独立发展。那么,依托于微信生态的视频号,未来将迎来哪些精彩发展呢? 让我们一同来揭开“视频号小店”的神秘面纱,了解一下玩法…

有色金属矿山采选智能工厂数字孪生可视化,推进矿采选业数字化转型

有色金属矿山采选智能工厂数字孪生可视化,推进矿采选业数字化转型。随着科技的不断发展,数字化转型已经成为各行各业发展的必然趋势。有色金属矿采选业作为传统工业的重要组成部分,也面临着数字化转型的挑战。为了更好地推进有色金属矿采选业…

百无聊赖之JavaEE从入门到放弃(十七)时间处理相关类

目录 一.Date 时间类 二.DateFormat 类和 SimpleDateFormat 类 三.Calendar 日历类 “时间如流水,一去不复返”,时间是一维的。所以,我们需要一把刻度尺来表达和度 量时间。在计算机世界,我们把 1970 年 1 月 1 日 00:00:00 定…

张维迎《博弈与社会》多重均衡与制度和文化(4)路径依赖的困惑

在前述计算机产品标准化的问题中,有两个纳什均衡:都生产有5.25英寸软盘驱动器的计算机和都生产有3.5英寸软盘驱动器的计算机。假设一开始企业只能生产有5.25英寸软盘驱动器的计算机,生产3.5英寸软盘驱动器计算机的技术随后出现,企…

Next.js如何正确处理跨域问题?

以前一直使用Vue来写前端。去年下半年接手了一个基于React Next.js的项目,于是顺带学习了一下Next.js。由于Next.js的特点,这个项目的前后端是放在一起的。一开始没什么问题,看了半天文档就上手了。 上周我们需要在另一个网页项目中&#x…

C#,桌面游戏编程,数独游戏(Sudoku Game)的算法与源代码

本文包括以下内容: (1)数独游戏的核心算法; (2)数独游戏核心算法的源代码; (3)数独游戏的部分题目样本; (4)适老版《数独》的设计原则…

C#,哥伦布数(Golomb Number)的算法与源代码

1 哥伦布数(Golomb Number) 哥伦布数(Golomb Number)是一个自然数的非减量序列,使得n在序列中正好出现G(n)次。前几个15的G(n)值为:1 2 2 3 3 4 4 4 5 5 5 6…

计算机图形学 实验

题目要求 1.1 实验一:图元的生成:直线、圆椭区域填充 你需要完成基本的图元生成算法,包括直线和椭圆。 在区域填充中,要求你对一个封闭图形进行填充。你需要绘制一个封 闭图形(例如多边形),并选…

Hadoop3.x基础(3)- MapReduce

来源: B站尚硅谷 目录 MapReduce概述MapReduce定义MapReduce优缺点优点缺点 MapReduce核心思想MapReduce进程常用数据序列化类型MapReduce编程规范WordCount案例实操本地测试提交到集群测试 Hadoop序列化序列化概述自定义bean对象实现序列化接口(Writable&#xff…

新手不会Git也能玩Github吗?

新手不会Git也能玩Github吗? 前言使用Github的准备步骤使用一种访问外网资源的方法(这一步才是新手最容易)注册账号 创建一个自己的仓库创建完仓库后的界面 搜索你想要的代码类型以搜索坦克大战为例以下载烟花代码为例 总结 前言 说到Github&…

人工智能福利站,初识人工智能,机器学习,第四课

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

我已经入驻多多

我已经入驻多多面包多平台 啦! 作为一位专注于帮助人们部署Python环境、探索人工智能和JavaEE技术,并创作计算机课程设计相关作品的创作者。我的作品类型涵盖了各种技术领域,旨在为学习者提供实用的资源和指导。 在CSDN拥有1100个粉丝的基础上&#x…

arcgis javascript api4.x加载非公开或者私有的arcgis地图服务

需求: 加载arcgis没有公开或者私有的地图服务,同时还想实现加载时不弹出登录窗口 提示:​ 下述是针对独立的arcgis server,没有portal的应用场景; 如果有portal可以参考链接:https://mp.weixin.qq.com/s/W…

MapStruct 使用

MapStruct最详细的使用教程,别在用BeanUtils.copyProperties () mapstruct使用和详解 项目背景 之前查看网上别人写的文章,很多都提到了BeanUtils(org.springframework.beans) 利用反射性能比较差。大家都推荐使用 MapStruct。因为这个组件使用 Java 原…

zookeeper 应该这样学

ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分…

C# 使用 MailKit 接收邮件(附demo)

C# 使用 MailKit 接收邮件(附demo) 介绍安装包(依赖)案例简单代码 获取附件核心代码完整代码 介绍一下POP3 介绍 MailKit 是一个开源的 C# 邮件处理库,用于在应用程序中发送和接收电子邮件。它提供了一个强大且易于使…

Redis核心技术与实战【学习笔记】 - 6.Redis 的统计操作处理

1.前言 在 Web 业务场景中,我们经常保存这样一种信息:一个 key 对应了一个数据集合。比如: 手机 APP 中的每天用户登录信息:一天对应一系列用户 ID。电商网站上商品的用户评论列表:一个商品对应了一些列的评论。用户…

【云原生之kubernetes系列】--污点与容忍

污点与容忍 污点(taints):用于node节点排斥Pod调度,与亲和效果相反,即taint的node排斥Pod的创建容忍(toleration):用于Pod容忍Node节点的污点信息,即node节点有污点,也将新的pod创建…

Ubuntu远程连接登录信息解读(ubuntu登录信息、远程登录信息)

文章目录 1. Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-100-generic aarch64)2. 三个链接是官方提供的文档、管理工具和技术支持3. System information as of Thu 01 Feb 2024 03:30:45 PM HKT4. System load: 1.16:系统负载指数5. Processes: 1096系统正在运…

【AI视野·今日Robot 机器人论文速览 第七十七期】Mon, 15 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Mon, 15 Jan 2024 Totally 14 papers 👉上期速览✈更多精彩请移步主页 Daily Robotics Papers Learning Joint Space Reference Manifold for Reliable Physical Assistance Authors Amirreza Razmjoo, Tilen Brecelj, Kri…