PV操作解决经典进程同步问题

一.经典同步问题

在学习《操作系统》时,会接触到进程的概念,其中不可避免的接触到进程同步问题,今天我们用熟悉的PV操作解决一些经典的进程同步问题。

二.生产者-消费者问题

1.问题描述

问题描述:一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或一个消费者从中取出消息。

2.问题分析

  • 1)关系分析。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,它们也是同步关系。
  • 2)整理思路。这里比较简单,只有生产者和消费者两个进程,正好是这两个进程存在着互斥关系和同步关系。那么需要解决的是互斥和同步PV操作的位置。
  • 3)信号量设置。信号量mutex 作为互斥信号量,用于控制互斥访问缓冲池,互斥信号量初值为1;信号量full用于记录当前缓冲池中的“满”缓冲区数,初值为0。信号量empty用于记录当前缓冲池中的“空”缓冲区数,初值为n。

3.PV描述

生产者-消费者进程的描述如下:

semaphore mutex=1 ;            //临界区互斥信号量
semaphore empty=n;             //空闲缓冲区
semaphore full=0;              //缓冲区初始化为空producer() {                  //生产者进程while (1) {produce an item in nextp;      //生产数据P (empty); (要用什么, p一下)    //获取空缓冲区单元P (mutex); (互斥夹紧)           //进入临界区add nextp to buffer; (行为)    //将数据放入缓冲区V (mutex) ;(互斥夹紧)           //离开临界区,释放互斥信号V(full); (提供什么, V一下)      //满缓冲区数加1}
}consumer() {                         //消费者进程while(1) {P (full) ;                   //获取满缓冲区单元P (mutex) ;                         //进入临界区remove an item from buffer;        //从缓冲区中取出数据V (mutex) ;                        //离开临界区,释放互斥信号量V (empty) ;                        //空缓冲区数加1consume the item;                  //消费数据}
}

三.复杂生产者-消费者问题

1.问题描述

问题描述:桌子上有一个盘子,每次只能向其中放入-一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈才可向盘子中放-一个水果;仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出。

2.问题分析

1)关系分析。这里的关系要稍复杂一些。由每次只能向其中放入一只水果可知,爸爸和妈妈是互斥关系。爸爸和
女儿、妈妈和儿子是同步关系,而且这两对进程必须连起来,儿子和女儿之间没有互斥和同步关系,因为他们是选择条件执行,不可能并发,如图所示。

在这里插入图片描述

2)整理思路。这里有4个进程,实际上可抽象为两个生产者和两个消费者被连接到大小为1的缓冲区上。

3)信号量设置。首先将信号量plate 设置互斥信号量,表示是否允许向盘子放入水果,初值
为1表示允许放入,且只允许放入一个。信号量apple表示盘子中是否有苹果,初值为0
表示盘子为空,不许取,apple= 1表示可以取。信号量orange表示盘子中是否有橘子,
初值为0表示盘子为空,不许取,orange= 1表示可以取。

3.PV描述

解决该问题的代码如下:

semaphore plate=1, apple=0, orange=0;dad() {           //父亲进程while(1) {prepare an apple;P (plate) ;							//互斥向盘中取、放水果put the apple on the plate;			//向盘中放苹果V(apple) ;							//允许取苹果}
}mom() {			//母亲进程while (1) {prepare an orange;P(plate) ;							//互斥向盘中取、放水果put the orange on the plate;		//向盘中放橘子V (orange) ;						//允许取橘子}
}son() {			//儿子进程while (1) {P (orange) ;						//互斥向盘中取橘子take an orange from the plate;V(plate) ;							//允许向盘中取、放水果eat the orange;}
}daughter() {	//女儿进程while(1) {P (apple) ;							// 互斥向盘中取苹果take an apple from the plate;V(plate) ;							//允许向盘中取、放水果eat the apple ;}
}

四.读者-写者问题

1.问题描述

问题描述:有读者和写者两组并发进程,共享-一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时,则可能导致数据不一致的错误。因此要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任意一 个写者在完成写操作之前不允许其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出。

2.问题分析

1)关系分析。由题目分析读者和写者是互斥的,写者和写者也是互斥的,而读者和读者不存在互斥问题。

2)整理思路。两个进程,即读者和写者。写者是比较简单的,它和任何进程互斥,用互斥信号量的P操作、V操作即可解决。读者的问题比较复杂,它必须在实现与写者互斥的同时,实现与其他读者的同步,因此简单的一对P操作、V操作是无法解决问题的。这里用到了一个计数器,用它来判断当前是否有读者读文件。当有读者时,写者是无法写文件的,此时读者会一直占用文件, 当没有读者时,写者才可以写文件。同时,这里不同读者对计数器的访问也应该是互斥的。

3)信号量设置。首先设置信号量count为计数器,用于记录当前读者的数量,初值为0;设置mutex为互斥信号量,用于保护更新count变量时的互斥;设置互斥信号量rw,用于保证读者和写者的互斥访问。

3.PV描述

代码如下:

int count=0;						//用于记录当前的读者数量
semaphore mutex=1 ;					//用于保护更新count变量时的互斥
semaphore rw=1;						//用于保证读者和写者互斥地访问文件writer(){while(1) {P (rw) ;					//互斥访问共享文件writing;					//写入V (rw) ;					//释放共享文件}
}reader () {							//读者进程while(1) {P (mutex) ;					//互斥访问count变量if (count==0)				//当第一个读进程读共享文件时P (rw) ;				//阻止写进程写count++ ;					//读者计数器加1V (mutex) ;					//释放互斥变量countreading;					//读取P (mutex) ;					//互斥访问count变量count-- ;					//读者计数器减1if (count==0)				//当最后一一个读进程读完共享文件V(rw) ;					//允许写进程写V (mutex) ;					//释放互斥变量count}
}

五.哲学家进餐问题

1.问题描述

问题描述:一张圆桌边 上坐着5名哲学家,每两名哲学家之间的桌上摆一根筷子, 两根筷子中间是一碗米饭。哲学家们倾注毕生精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,才试图拿起左、右两根筷子(一根一根地拿起)。若筷子已在他人手,则需要等待。饥饿的哲学家只有同时拿到了两根筷子才可以开始进餐,进餐完毕后,放下筷子继续思考。

2.问题分析

1)关系分析。5名哲学家与左右邻居对其中间筷子的访问是互斥关系。

2)整理思路。显然,这里有5个进程。本题的关键是如何让一名哲学家拿到左右两根筷子而不造成死锁或饥饿现象。解决方法有两个:一是让他们同时拿两根筷子;二是对每名哲学家的动作制定规则,避免饥饿或死锁现象的发生。

3)信号量设置。定义互斥信号量数组chopstick[5]={1,1,1,1,1},用于对5个筷子的互斥访问。哲学家按顺序编号为0~4,哲学家i左边筷子的编号为i,哲学家右边筷子的编号为(i + 1)%5。

3.PV描述

为防止死锁发生,可对哲学家进程施加一些限制条件, 比如至多允许4名哲学家同时进餐;仅当一名哲学家左右两边的筷子都可用时,才允许他抓起筷子;对哲学家顺序编号,要求奇数号哲学家先拿左边的筷子,然后拿右边的筷子,而偶数号哲学家刚好相反。制定的正确规则如下:假设采用第二种方法,当一名哲学家左右两边的筷子都可用时,才允许他抓起筷子。

semaphore chopstick[5]={1,1,1,1,1};			 //初始化信号量
semaphore mutex=1 ;							//设置取筷子的信号量Pi(){										//i号哲学家的进程do {P (mutex) ;							//在取筷子前获得互斥量P (chopstick[i]) ;					//取左边筷子P (chopstick[ (i+1)85]) ;			//取右边筷子V (mutex) ;							//释放取筷子的信号量eat;								//进餐V (chopstick[i]) ;					//放回左边筷子V (chopstick[ (i+1)85]) ;			//放回右边筷子think;								//思考} while(l) ;
}

六.吸烟者问题

1.问题描述

问题描述:假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉它,但要卷起并抽掉一支烟, 抽烟者需要有三种材料:烟草、纸和胶水。三个抽烟者中,第一个拥有烟草,第二个拥有纸,第三个拥有胶水。供应者进程无限地提供三种材料,供应者每次将两种材料放到桌子上,拥有剩下那种材料的抽烟者卷一根烟并抽掉它, 并给供应者一个信 号告诉已完成,此时供应者就会将另外两种材料放到桌上,如此重复(让三个抽烟者轮流地抽烟)。

2.问题分析

问题分析:

  • 1)关系分析。供应者与三个抽烟者分别是同步关系。由于供应者无法同时满足两个或以上的抽烟者, 三个抽烟者对抽烟这个动作互斥( 或由三个抽烟者轮流抽烟得知)。
  • 2)整理思路。显然这里有4个进程。供应者作为生产者向三个抽烟者提供材料。
  • 3)信号量设置。信号量offer1, offer2, offer3分别表示烟草和纸组合的资源、烟草和胶水组合的资源、纸和胶水组合的资源。信号量finish用于互斥进行抽烟动作。

3.PV描述

代码如下:

int num=0;				//存储随机数
semaphore offer1=0;		//定义信号量对应烟草和纸组合的资源
semaphore offer2=0;		//定义信号量对应烟草和胶水组合的资源
semaphore offer3=0;		//定义信号量对应纸和胶水组合的资源
semaphore finish=0;		//定义信号量表示抽烟是否完成process P1() {		//供应者while(1) {num++ ;num=num%3;if (num==0)V(offer1) ;				//提供烟草和纸else if (num==1)V (offer2) ;			//提供烟草和胶水elseV(offer3) ;				//提供纸和胶水任意两种材料放在桌子上;P (finish) ;}
}process P2() {		//拥有烟草者while(1) {P(offer3) ;拿纸和胶水,卷成烟,抽掉;V(finish) ;}
}process P3() {		//拥有纸者while (1) {P(offer2) ;拿烟草和胶水,卷成烟,抽掉;V(finish) ;}
}process P4() {		//拥有胶水者while (1) {P (offerl) ;拿烟草和纸,卷成烟,抽掉;V(finish) ;}
}

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

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

相关文章

Linux中使用du命令来查看目录的大小

在Linux中,你可以使用du命令来查看目录的大小。下面是一些常用的du命令选项: -h:以人类可读的格式显示文件大小。-s:仅显示总大小,而不显示每个子目录的大小。-c:显示总大小,并在最后一行显示总…

汽车交流充电桩控制主板的电路设计

汽车充电桩控制主板的电路设计 你是否曾经遇到过汽车没油的问题?但是,随着电动汽车的普及,充电问题也变得越来越重要。而汽车充电桩控制板电路设计则是解决这一问题的关键。 汽车充电桩控制板电路设计包括硬件电路设计、软件电路设计和安全性设计。硬件…

[vulnhub]DC2

文章目录 [vulnhub]DC2信息收集flag1flag2cewlwpscan flag3什么是rbash? flag4flag5git提权 总结 [vulnhub]DC2 信息收集 扫ip,有两种方式:arp、nmap nmap -sP 192.168.56.0/24 -T4arp-scan -l192.168.56.137 扫端口: nmap -…

TEE GP(Global Platform)认证方案

TEE之GP(Global Platform)认证汇总 一、GP认证方案 二、GP认证方案分类 参考: GlobalPlatform Certification - GlobalPlatform

微服务系列(1)-who i am?

微服务系列(1)-我是谁 应用架构的演化 简单来说系统架构可以分为以下几个阶段:复杂的臃肿的单体架构-SOA架构-微服务 单体架构及其所面临的问题 在互联网发展初期,用户数量少,流量小,硬件成本高。因此…

关于axios请求java接口中的@RequestParam、@PathVariable及@RequestBody不同接参类型的用法

一、前端传json对象,后端指定接收json对象中的哪个参数。 (1)前端请求 axios({//请求方式method:post,//后端接口路径url:http://127.0.0.1:8080/api/deleteUserById,//注意这里使用的是params,该属性负责把属性名和属性值添加到url后面,一般和get配合使…

Python版day55

392. 判断子序列 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一…

pytorch学习-线性神经网络——softmax回归+损失函数+图片分类数据集

1.softmax回归 Softmax回归(Softmax Regression)是一种常见的多分类模型,可以用于将输入变量映射到多个类别的概率分布中。softmax回归是机器学习中非常重要并且经典的模型,虽然叫回归,实际上是一个分类问题 1.1分类与…

【C++】写一个函数实现系统时间与输入时间进行比较

目录 1 代码 2 运行结果 时间比较函数: 输入为字符串2023-7-28,将字符串分解为年、月、日信息。 获取系统时间2023-7-24,然后将输入时间和系统时间进行比较,输出比较结果。 1 代码 #include <ctime> #include<iostream> #include<vector> using names…

【Java】JUC并发编程-进程线程

目录 一、什么是JUC二、进程和线程1、进程2、线程 三、线程的六种状态四、wait与sleep的区别五、并发与并行1、串行模式2、并行模式3、并发模式4、管程 六、用户线程与守护线程1、用户线程&#xff08;自定义线程&#xff09;2、守护线程&#xff08;比如垃圾回收&#xff09; …

Python爬虫学习笔记(十三)————CrawlSpider

目录 1.CrawlSpider介绍 2.使用方法 &#xff08;1&#xff09;提取链接 &#xff08;2&#xff09;模拟使用 &#xff08;3&#xff09;提取连接 &#xff08;4&#xff09;注意事项 3.运行原理 4.Mysql 5.pymysql的使用步骤 6.数据入库 &#xff08;1&#xff09;s…

【100个 Unity实用技能】 | Unity中Text文本框 和 InputField文本输入框 内容换行问题【文末送书】

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…

游戏开发中的Jenkins

1.安装搭建环境可自行百度或者点击下方链接参考 .【游戏开发进阶】教你Unity通过Jenkins实现自动化打包&#xff0c;打包这种事情就交给策划了&#xff08;保姆级教程 | 命令行打包 | 自动构建&#xff09; 2.Jenkins复制和导出导入job 一、同一个Jenkins中复制job 如果是同…

Ceph的应用

文章目录 一、创建 CephFS 文件系统 MDS 接口1&#xff09;在管理节点创建 mds 服务2&#xff09;查看各个节点的 mds 服务3&#xff09;创建存储池&#xff0c;启用 ceph 文件系统4&#xff09;查看mds状态&#xff0c;一个up&#xff0c;其余两个待命&#xff0c;目前的工作的…

应该选云服务器还是物理服务器

应该选云服务器还是物理服务器 一、为什么需要云服务器或独立服务器取代共享主机 在最早之前&#xff0c;大多数的网站都是共享主机开始的&#xff0c;这里也包含了云虚拟机。这一类的站点还有其他站点都会共同托管在同一台服务器上。但是这种共享机只适用于小的网站&#xff…

Docker-compose容器编排

Docker-Compose介绍 Compose 是 Docker 公司推出的一个工具软件&#xff0c;可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml&#xff0c;写好多个容器之间的调用关系。然后&#xff0c;只要一个命令&#xff0c;就能同时启动/关…

项目里程碑有什么作用?设置里程碑时应注意什么?

正如 "里程碑 "一词的原意是表示所走距离的标记&#xff0c;项目中的里程碑也代表着迄今为止已完成的任务或活动。但实际上&#xff0c;里程碑的作用远不止于此。 项目里程碑为何重要&#xff1f; 项目的成功取决于细节。项目里程碑之所以重要&#xff0c;是因为它…

微信小程序的个人博客--【小程序花园】

微信目录集链接在此&#xff1a; 详细解析黑马微信小程序视频–【思维导图知识范围】难度★✰✰✰✰ 不会导入/打开小程序的看这里&#xff1a;参考 让别人的小程序长成自己的样子-更换window上下颜色–【浅入深出系列001】 文章目录 本系列校训啥是个人博客项目里的理论知识…

如何在3ds max中创建可用于真人场景的巨型机器人:第 1部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 创建主体 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 在左侧视口中&#xff0c;按键盘上的 Alt-B 键。它 打开视口配置窗口。 打开“锁定缩放/平移”和“匹配位图”选项。单击“文件”并转到参考 …

JSON格式Python,Java,PHP等封装获取淘宝商品详情SKU数据API方法

淘宝是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取淘宝天猫商品详情SKU详细数据&#xff0c;您可以通过开放平台的接口或者直接访问淘宝天猫商城的网页来获取商品详情Sku信息。以下是两种常用方法的介绍&…