CHS_06.2.3.4_2+用信号量实现进程互斥、同步、前驱关系

CHS_06.2.3.4_2+用信号量实现进程互斥、同步、前驱关系

  • 知识总览
    • 信号量机制实现进程互斥
    • 信号量机制实现进程同步
    • 信号量机制实现前驱关系
  • 知识回顾

各位同学 大家好 在这个小节中 我们要学习怎么用信号量机制来实现进程的同步互制关系

知识总览

在这里插入图片描述

那么 我们之前学习了互斥的几种软件实现方式和硬件实践方式

但是这些实现方式都有一个共同的缺点 就是没有办法实现让权等待这个原则

而信号量机制当中设置了进程的阻塞和唤醒就刚好可以解决让权等待这个问题

所以信号量机制是一种更先进的解决方式 那我们上个小节介绍了信号量是什么 信号量机制的pv操作 分别做了一些什么事情

建议是不要先一头钻进大马里 而是要注意理解信号量背后的含义

其实一个信号量 它无非就是对应了某一种资源 而信号量的值

表示的是这种资源的剩余数量 如果它的值小于零的话 那么就说明此时至少有一个进程正在等待

这种资源 而 如果一个进程执行了对某一个信号量的p操作 那么他想表达的其实是

申请一个这种资源 如果资源不够的话 这个进程就会执行block原语主动的阻塞

而如果一个进程他对某一个信号量执行V操作的话 那么就说明这个进程想要释放一个这种资源 想要产生一个这个资源

如果此时有进程正在等待这个资源 那么他就会用we cup原语唤醒一个正在等待的阻塞进程

那我们来看一下如何利用这种机制实现进程的互斥 那经过之前的学习我们知道

信号量机制实现进程互斥

在这里插入图片描述

系统当中的某一些资源是必须互斥访问的 而访问这种系统资源的那段代码叫做临界区

所以 既然这个资源需要互斥访问 那么就说明同一时刻只能有一个进程进入临界区代码

所以 要解决进程互斥的问题 我们首先要做的是要划定临界区

也就是说 哪一段代码是用于访问临界资源的 另外 为了实现对临界区的互斥访问 我们需要设置一个互斥信号量

叫mutex mutex就是英文的互斥的意思 把这个信号量的初始值设为一

就像这个样子 然后当一个进程要进入临界区之前 需要对new tax执行p操作

在出了临界区之后 需要对new tax执行v操作 所有的进程都是这样 这样就可以实现各个进程对临界区这段代码的

互斥访问了 那我们在开篇提到过信号量 它其实就是用于表示某一种资源

那我们可以这么理解这个互斥信号量 mutex 我们可以认为他所表示的资源是

进入临界区的名额 它的初始值为一那么就说明刚开始可以进入这个临界区的名额只有一个

那当某一个进程对new tax执行p操作的时候 其实在背后的逻辑就是说

我想申请一个进入临界区的名额 那如果名额这种资源此时还有剩余的话

那么这个进程就可以顺利进入临界区 而如果此时另一个进程也尝试

执行p操作 也就说他也尝试申请一个名额 那么我们知道这个名额总共只有一个 所以此时这个进程对于名额这种资源的申请就得不到满足

他必须阻塞在这个地方等待 而直到这个进程他使用完临界区之后

他又对mutex执行v操作 也就说他会归还这个名额 那在这个时候就可以把p二进程给唤醒 让他进入临界区

所以可以看到 我们用这样的方式就实现了各个进程对临界区的互斥访问

那在上个小节中 我们对信号量是这么定义的 三部分 这个其实就是信号量的

英文单词那这个地方需要提醒大家的是 如果题目没有特别说明的话

我们对一个信号量的定义只需要像这个题目这样 semaphore mutex等于多少

用用这种方式来定义就可以了 我们并不需要写出这个信号量的数据结构 当然 大家也要能够自己写出信号量定义的这个数据结构

那这个地方 我们虽然使用了这样一个简单的方式来定义 但是只要我们用semaphore这个关键字来开头的话 那么就意味着这个信号量 它并不是整形信号量

它是一个记录型的信号量 也就是说 这个信号量是带有排队阻塞的这个功能的

并不会盲等 那这是大家在做题的时候需要注意的第一个点 第二个点 对于不同的临界资源 我们需要设置不同的互斥信号量

比如说 我们的系统中有p一和p二这两个进程 他们需要啊访问打印机这种临结资源

而p三和p四他们需要访问摄像头这个临界资源 那在这种情况下

我们要给访问打印机的零接区设置一个信号量mutex一要给访问摄像头的这个零接区设置另一个信号量mutex二

另外 必须注意的是 pv操作必须承兑的出现 如果缺少这个p操作

那么就没办法保证各个进程互斥的访问 临接资源的这个事情 如果缺少V操作的话 那么就有可能会导致某一些进程阻塞了 之后永远得不到唤醒

那这是大家在做题的时候需要注意的三个点 接下来我们再来看第二个问题

怎么用信号量机制来实现进程的同步 那进程的同步这个概念我们已经有一段时间没提了

信号量机制实现进程同步

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

这再来 简单的复习一下 所谓的同步 就是说要让各个病发执行的进程按照要求的顺序有序的推进

比如说有p一p二这两个进程 当他们在系统当中并发的执行的时候

由于系统的环境很复杂 所以操作系统在调度的时候 有可能是p一线上处理机运行 有可能是p二线上处理机运行

比如说p二线上处理机运行了代码四和代码五而此时他时间片用完了 那又切换回p一

然后p一运行了代码一代码二接下来又切换为p二运行了代码六等等等等

总之 由于这两个进程在系统中是并发的运行的 因此他们之间的这些代码执行先后顺序是我们所不可预知的

而有的时候 我们又必须让这些代码的执行顺序按照我们想要的那种方式进行

比如说 当这两个进程并发执行的时候 p二的代码四必须基于p一的代码一代码二的

运行结果才可以执行 那么在这种情况下 我们就必须保证代码四是在代码一和代码二之后才执行的

所以这就是所谓进程同步的问题 我们要解决他们之间并发运行存在的异步性

让他们按照我们想要的顺序相互配合着有序的推进 那我们怎么用信号量机制来实现进程同步呢

首先 我们要做的就是要分析在什么地方需要实现所谓的同步关系

也就是说要在什么地方需要保证所谓疫前以后的两个操作 某一个操作一定要在前

而另一个操作一定要在后 这是所谓疫前以后的意思 第二步我们要设置一个同步信号量s

他的初始值为零那以刚才p一p二为例 如果代码四必须在代码二之后才能执行的话

那么 p二在代码四之前需要对s这个信号量执行一个p操作 而p一在代码二之后需要对s这个信号量执行一个v操作

我们来分析一下会发生什么情况 假如刚开始是p一被调度 他线上处理运行

那么p一运行了代码一代码二之后执行了v操作 这个v操作会导致s的值加一

这个值本来是零那在加一之后 s的值变为了一那接下来如果p二上处理机运行的话

当他对s这个信号量执行p操作的时候 就会发现s的值是一

表示有可用的资源 所以p二这个进程并不会被阻塞 它就可以往下执行代码四

那刚才我们所说的这种情况是先执行了代码一代码二然后再执行了代码四

那再来看第二种情况 假设刚开始是p 二先上处理机运行

那么 p二首先会对s这个信号量执行一个p操作 那 由于s的值刚开始是零

所以p二会在这个地方被阻塞 他暂时没办法运行代码四而直到p一上处理机运行运行了代码一代码二之后

他对s这个信号量执行 赢得了一个v操作 那根据上个小节我们讲的逻辑

这个v操作会唤醒此时正在等待s这个信号量的进程 也就是会唤醒p二这个进程

也就是说 只有p一执行了v操作之后 p二才有可能被唤醒 上处理机运行

那这就保证了代码21定是在代码四之前执行的 我们依然是用信号量代表某种资源 这样的思路来分析这个问题

这个信号量s 它表示某种资源 那具体是什么资源没必要关心

刚开始s的值是零就意味着刚开始这种资源是没有的 而p二要执行

代码四之前 他一定需要获得这个资源 所以他在执行代码四之前需要执行一个p操作

但是呢 这种资源只有p一能够释放 所以当p二申请这种资源得不到满足的时候 它就会被阻塞

而由于这种资源只有p一能够产生 所以只有p一能够在某一个特定的位置唤醒p二这个进程

所以这就实现了进程之间的同步关系 那么我自己对这种同步关系进行了一个小小的总结

如果要实现进程之间的同步 那么我们需要在前操作之后执行v操作

在后操作之前执行p操作 什么意思呢 代码二是必须在前执行的

代码四是必须在后执行的 所以代码二是所谓的必须在前的这个操作

代码四是必须在后执行的操作 因此我们需要在前操作 也就是代码二之后

执行一个v操作 在后操作 也就是代码四之前执行一个p操作

那我们再把这个表述精简一点 就是前微后批 我们设置一个信号量 初始值为零表示刚开始 这种资源是没有的

而只有执行前面那个操作的进程可以释放这种资源 所以这是前威

而执行后面那个操作的进程 在他的操作之前需要申请一个这个资源

所以这是后屁 当他申请的这个资源得不到满足的时候 这个进程就会阻塞

只能由前面那个进程把它唤醒 那这个技巧是解决进程同步问题的一个关键

我们来看一下怎么利用这个技巧来解决更复杂的进程同步问题 我们的课本上专门讲了一个叫做进程的前驱关系

信号量机制实现前驱关系

在这里插入图片描述

那这个图很好理解 其实他想表达的就是 只有s一这个事件发生了之后 或者说只有s一这个代码执行了之后

才能执行s二和s三而只有执行了s二之后 才可以执行s四和s五

另外 只有执行了s三s四s五之后才能执行s六

那我们假设这几句代码分别是p一p二p三p41直到p六这几个进程需要执行的

那我们来看一下怎么用信号量机制解决这么复杂的进程之间从不问题

首先 我们需要分析的是 在这个前驱图当中 其实它包含了很多对的

进程同步关系每一条线其实就是代表一个疫前以后的同步问题

所以我们需要给每一对这种疫情以后的这种同步关系都设置一个同步信号量

那我们这就分别用a b c d e f g来分别表示啊 每一个这种同步关系

并且同步信号量的初值都是零也就说这种资源刚开始是没有的 这种资源只能由前面这个操作相关的进程

来产生那 由于s一必须在前 s二必须在后 所以当s一这个事件发生了之后 也就这个前操作之后

我们需要对相应的信号量执行一个V操作 这是前威 而当后面这个操作

发生之前 我们需要对相应的这个同步信号量执行一个p操作 这是后p

前面这个操作完成了就执行v 后面这个操作开始前就执行p前微后p

那其他的所有的这些同步关系也都是一葫芦画瓢 所有都是前卫后皮

那这样的话 我们就可以很轻松的用p v操作实现这么复杂的进程之间的同步关系

简单的对照图看一下s一这个操作完成了之后 它需要执行两个v操作 一个是va 一个是vb

那对应的就是代码的这个部分 s一之后执行v a和v b 而s二这个代码执行之前 它需要执行一个p a操作

所以s二之前有一个p a 而s二执行之后 他又需要对c和d分别执行v操作 所以它后面又有v c和v d

那再来看s六s六这个代码执行之前 它需要对这几个同步信号量都执行p操作

所以s六之前需要进行p e pf和pg 总之 虽然这个同步关系有很多层

但是我们只要知道前威后癖这个技巧 我们就可以把这个同步关系很清晰的 很轻松的表达出来了

那这个地方希望大家暂停来分析一下这个代码 如果各个进程以不同的顺序上处理机运行的话

到底能不能实现我们这表达的这么多的同步关系呢 比如说刚开始是p五这个进程上处理机运行

那么 他所要做的第一件事是对d这个信号量执行一个p操作 而由于d刚开始的值为零所以他会被阻塞在这个地方

因此 接下来就会发生进程调度切换为另一个进程 那假设接下来上处理机运行的是p二这个进程

那他对a这个信号量执行p操作 同样的 他也会被阻塞在这个地方 那除非p一进程上处理机运行了

当他执行了s一这个代码之后 他会执行v a和v b操作 那v a这个操作会把p二这个进程给唤醒

所以接下来p二这个进程才会执行s二这个代码 也就是说 s二肯定是在s一之后执行的 这和这个前驱图所反映的关系是一样的

那当p二执行了s二这个代码之后 他又会对d这个信号量执行一个v操作

这个v操作又会唤醒刚才被阻塞的p五这个进程 那之后p五才可以执行s五这句代码

所以对于d这个信号量的p v操作也保证了s五这句代码

一定是在s二这句代码之后才能执行的 这也和我们这所反映的这一对同步关系是一样的

那剩下的就不再展开 大家可以暂停自己 给自己出一些题 来分析一下这些同步关系到底是如何被满足的

好的 那么这个小节中 我们介绍了很重要的知识点 怎么用信号量机制实现进程的互斥同步

几乎每一年都至少有个大题是要考察这个信号量机制实现互制和同步的

所以对于这个小节的掌握是十分重要的 那么如果要用信号量机制实现进程互斥的话 我们可以设置一个初始值为一的互斥信号量

知识回顾

在这里插入图片描述

并且在临界区之前执行p操作 临界区之后执行v操作 而如果要实现进程的同步的话 那么我们需要设置一个

初始值为零的同步信号量 另外 需要在前操作之后执行v操作

需要在后操作之前执行p操作 也就是前微后p 用这样的方式就可以保证

进程之间疫情以后的这种同步关系了 那这是互斥和同步问题的一个基本套路

那最后我们所介绍的进程的前驱关系 他本质上也是一个进程同步的问题 只不过他是多级的同步

但只要我们能掌握前卫后癖的这种技巧的话 前驱问题其实也很好解决

那对于信号量机制的考察除了实现互斥和同步之外 有的时候有可能会考察

用信号量机制来实现资源分配的问题 比如说系统中有三个打印机 那么这种情况下我们就需要把

打印机对应的那个信号量初始值设置为三然后当一个进程需要申请使用这个资源的时候 就需要对这个资源所对应的信号量执行p操作

然后使用完了之后 就需要执行v操作 那这一点其实只要掌握了信号量 他在背后所表示的逻辑也并不难理解

那这个小节中 我们只是简单的介绍了pv操作的一个简单的使用技巧

并没有涉及实际的题目 那从下个小节开始 我们会介绍几个很经典的进程同步问题用来帮助大家

更好的学习如何用信号量机制解决复杂的进程同步 进程互斥的问题

好的 那么以上就是这个小节的全部内容

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

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

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

相关文章

只有一台显示器,如何实现同时显示4台主机的HDMI信号?

HDMI画面分割器概述 HDMI画面分割器属于画面分割器中的一种,因为其信号接口是HDMI接口而得其名,多用于监控、多媒体、视频会议等常见的场景 HDMI画面分割器-图 HDMI画面分割器工作原理 使用硬件方式将多路HDMI信号以多种不同的模式分割显示在同一个显示…

香蕉派BPI-M7 瑞芯微RK3588 人工智能开源硬件开发板公开发售

香蕉派(Banana Pi) BPI-M7瑞芯微K3588开源硬件单板计算机公开销售,支持WiFi 6和BT5.2,硬件有3个版本:8G Ram64G eMMC, 16G Ram128 eMMC和32G Ram128 eMMC 香蕉派BPI-M7采用睿芯最新旗舰RK3588八核64位处理器,最高频率为2.4GHz, 6 TOPS NPU&…

谷歌把GenAI装进Chrome

谷歌不甘示弱,在其Chrome浏览器中引入了新的实验性生成式AI功能,以简化并为用户提供更高效的浏览体验。 值得注意的是,微软去年推出了Edge浏览器和人工智能驱动的必应搜索引擎的集成。随着Chrome M121版本的发布,谷歌打算利用最新…

2024年美赛赛前复习大纲

CC数模-优质解答 引言 数学建模是一个将数学理论和方法应用于解决现实世界问题的过程。在数学建模比赛中,学生需要运用自己的数学知识和技能,解决给定的复杂问题。这不仅是一次展示自己能力的机会,也是一次学习和成长的过程。随着比赛的临近…

Wheeltec小车的开发实录(2)

小车初步启动控制 小车终端运行l: roslaunch turn_on_wheeltec_robot turn_on_wheeltec_robot.launch 控制终端运行(多机通讯设置后,可以不必执行这一步) export ROS_HOSTNAME192.168.224.122(控制终端ip)export R…

【Tomcat与网络8】从源码看Tomcat的层次结构

在前面我们介绍了如何通过源码来启动Tomcat,本文我们就来看一下Tomcat是如何一步步启动的,以及在启动过程中,不同的组件是如何加载的。 一般,我们可以通过 Tomcat 的 /bin 目录下的脚本 startup.sh 来启动 Tomcat,如果…

【HarmonyOS应用开发】UIAbility实践第二部分(六)

内容接上篇 【HarmonyOS应用开发】UIAbility实践第一部分(五) 末尾含示例源码 三、UIAbility的生命周期 当用户浏览、切换和返回到对应应用的时候,应用中的UIAbility实例会在其生命周期的不同状态之间转换。 UIAbility类提供了很多回调&a…

关于字符串处理

文章目录 关于字符串处理1、取字符串的长度2、跳过前面的字符3、取字符串右边的字符4、掐头去尾5、取倒数的范围6、删左留右7、删右留左8、查找替换9、大小写转换 关于字符串处理 1、取字符串的长度 [rootlocalhost ~]#strabcd1128 #定义变量 [rootlocalhost ~]#echo ${#str}…

IEEE| IceNet《IceNet for Interactive Contrast Enhancement》论文超详细解读(翻译+精读)

学习资料: 论文题目:《IceNet for Interactive Contrast Enhancement》(用于交互式对比度增强的IceNet)原文地址:export.arxiv.org/pdf/2109.05838v2.pdf 目录 ABSTRACT—摘要 翻译 精读 I. INTRODUCTION—简介 翻…

通俗易懂三大范式

通俗易懂三大范式 第一范式说的是每个字段不可再分 第二范式说的是不能存在部分依赖(不能由联合主键的部分就可以推出其他字段,必须整个联合主键才能推出其他字段) 第三范式说的是不能存在间接依赖(A(主键)→B,B→C…

瑞_23种设计模式_工厂模式

文章目录 1 什么是工厂模式案例案例代码 2 简单工厂模式(Simple Factory)2.1 简单工厂模式的结构2.2 案例改进——简单工厂模式2.3 案例改进代码实现2.4 简单工厂模式优缺点2.5 拓展——静态工厂 3 工厂方法模式(Factory Method)★…

【零基础学习CAPL】——CAN报文的发送(按下按钮同时周期性发送)

🙋‍♂️【零基础学习CAPL】系列💁‍♂️点击跳转 文章目录 1.概述2.面板创建3.系统变量创建4.CAPL实现4.1.函数展示4.2.全量报文展示5.效果1.概述 本章主要介绍使用CAPL和Panel在按下按钮时发送周期性CAN报文。 本章主要在“【零基础学习CAPL】——CAN报文的发送(配合P…

数组与字符串深度巩固

经过再三思考觉得今天就写一篇关于数组与字符串相关的文章吧!其中字符串主要通过练习来巩固知识亦或是获得新知识。好接下来将进行我们的学习时刻了。 首先我们来思考一个问题,你真的了解数组的数组名吗?数组名真的就单单一个名字而已吗&…

Mac安装配置JDK

Mac安装配置jdk 下载地址:https://www.oracle.com/java/technologies/downloads/#java8 下载jdk1.8及以上需要Oracle账号及密码 dokidoki811163.com\pass:Zywxmxbt1314… 安装jdk 双击安装包,点击.pkg,按照提示安装,配置环境之前…

微信小程序(二十八)网络请求数据进行列表渲染

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.GET请求的规范 2.数据赋值的方法 源码&#xff1a; index.wxml <!-- 列表渲染基础写法&#xff0c;不明白的看上一篇 --> <view class"students"><view class"item">&…

介绍一个超好用的API管理工具:Apipost

Apipost是一款集API调试、生成文档、Mock、测试于一体的协同工具。单个工具可以同时满足接口测试、生成/分享文档、Mock、流程测试等功能&#xff0c;还有超实用的多人多角色间实时协作的功能。将前端、后端、测试三种角色串联起来&#xff0c;从而实现工作流程无缝衔接、提高研…

【Qt】—— 项⽬⽂件解析

目录 &#xff08;一&#xff09;.pro⽂件解析 &#xff08;二&#xff09;widget.h⽂件解析 &#xff08;三&#xff09;main.cpp⽂件解析 &#xff08;四&#xff09;widget.cpp⽂件解析 &#xff08;五&#xff09;widget.ui⽂件解析 &#xff08;一&#xff09;.pro⽂…

P1083 [NOIP2012 提高组] 借教室

P1083 [NOIP2012 提高组] 借教室 题目描述 在大学期间&#xff0c;经常需要租借教室。大到院系举办活动&#xff0c;小到学习小组自习讨论&#xff0c;都需要向学校申请借教室。教室的大小功能不同&#xff0c;借教室人的身份不同&#xff0c;借教室的手续也不一样。 面对海…

net 一台路由器如何让两个不同网段的终端可以通信。

# 终端设备自己设置就行了 # 路由器的设置 The device is running! #################################################### <Huawei> Feb 1 2024 21:21:09-08:00 Huawei %%01IFPDT/4/IF_STATE(l)[0]:Interface GigabitEt hernet0/0/0 has turned into UP state. <…

C++层uevent获取

本文用的是#include <cutils/uevent.h> 主要讲述android中怎么在C层接收uevent uevent 是 kernel层向用户层发送的一个事件 首先创建一个线程用于循环去获取uevent void testUevent {//创建一个线程一直循环pthread_t thread;int ret pthread_create(&thread, nu…