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等技术内容,立即学习

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++杂货铺】详解类和对象 [下]

个人博客:代码菌-CSDN博客 专栏:C杂货铺_代码菌的博客-CSDN博客 目录 🌈前言🌈 📁 初始化列表(灰常重要) 📂 引入 📂 概念 📂 特性 📁 拓展构…

OG Trade在ZKX揭幕:一家基于Starknet的游戏化永续合约交易所

ZKX的 OG Trade通过内置游戏化和30分钟交易竞赛,为所有交易者创造机会,革新了永续合约交易模式。 2024年1月30日 — ZKX宣布推出OG Trade,这是一家基于Starknet的游戏化永续合约交易所,旨在满足短期交易者、高水平交易者和波段交易…

021 while循环详解

什么时while循环 int i 0; // 循环输出i&#xff0c;大于100时结束 while(i < 100){System.out.println(i);i; } int i 0; int sum 0; // 计算1-100的和&#xff0c;输出 while(i < 100){sum i;i; } System.out.println(sum); 什么是死循环 循环没有停止下来的条件…

Vue3嵌套ref小细节,自我解惑

前言&#xff1a; 作者在学习时&#xff0c;遇到代码如下&#xff1a; import { ref,watch } from vue const state ref({count:0}) const addState ()>{state.value.count } 对于方法中对对象中count的理解存在偏差 问题及解决&#xff1a; 误解&#xff1a; 认为是…

面对近期行情大起大落的伦敦银需要关注什么?

近期经常有听到投资者抱怨说&#xff0c;伦敦银价格没有明显趋势&#xff0c;很难做。确实&#xff0c;我们从日线图看&#xff0c;金价处于一个比较宽幅的横盘区间当中&#xff0c;近期的行情也是大涨大跌。投资者认为&#xff0c;面对大起大落的行情无从下手。下面我们就来讨…

会话管理技术

会话管理 会话管理是跟踪用户跨网页活动的过程。以在线购物商场为例。用户可以选择产品并将其添加到购物车中。用户转到其他页面时,购物车中仍然保留详细信息,以便用户查看购物车中的物品并下订单。 会话跟踪也可用于跟踪用户的偏好。例如,如果用户选择了多本小说,则向用…

内网安全:RDP WinRS WinRM SPN Kerberos 横向移动

目录 WinRM协议 RDP协议 域横向移动&#xff1a;RDP协议 RDP协议利用 一. 探针服务 二. 获取NTML Hash 明文密码 三. 连接执行 域横向移动&#xff1a;WinRM WinRS WinRM协议、WinRS命令利用 一. cs 内置端口扫描5985 二. 连接执行 三. 上线CS 四. CS插件横向移动…

基于springboot+vue的阿博图书馆管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

Springboot项目基础配置:小白也能快速上手!

推荐文章 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;一&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;二&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;三&#xff09; 给软件行业带来了春天—…

vue-cli项目运行流程介绍

一、前言 ​ 本文介绍 vue-cli搭建的项目运行流程&#xff0c;基于已经搭建好的基础项目。关于 vue-cli 构建项目的详细流程&#xff0c;可参考博文&#xff1a;使用vue脚手架构建项目 二、main.js 项目运行 会加载入口文件 main.js /* html文件中&#xff0c;通过script …

CTF盲水印工具:Blind-WaterMark安装

工具下载地址&#xff1a;GitCode - 开发者的代码家园 下载完毕后&#xff0c;只留这些东西就行 接下来需要安装两个依赖&#xff1a; opencv、matplotlib 直接pip install安装的话&#xff0c;工具使用会报错 所以需要到网站里挑选适合的版本进行安装 下载地址&#xff1…

DrissionPage多线程实践

DrissionPage多线程实践 背景&#xff1a;项目中需要抓取部分平台的数据&#xff0c;因为涉及到登录&#xff0c;且暂未实现接口登录。所以采用selenium登录后获取cookie传给requests的方式来实现。后了解到DrissionPage国产开源库&#xff0c;等于是把selenium和requests结合起…

部署YUM仓库服务

一、yum仓库 1. yum简介 yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红帽软件包管理器的缩写&#xff09;构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。 为什么会有依赖关系的发生 因为linux本身就是以系统简洁为自身优势&#xff0c;所以…

大数据信用报告应该去哪里查询比较好呢?

对于个人而言&#xff0c;大数据信用报告也变得越来越重要。那么&#xff0c;大数据信用报告应该去哪里查询呢?本文将为您详细介绍征信和大数据的区别&#xff0c;并推荐一个可靠的大数据平台。 首先&#xff0c;我们需要了解征信和大数据的区别 征信报告 依法采集、整理、保存…

day13_oop_抽象类_接口

今日内容 零、 复习昨日 一、作业 二、抽象 三、接口 零、 复习昨日 final的作用 最终的,修饰的类,属性,方法不能改变类不能继承,属性不能改变(常量),方法不能重写 static修饰方法的特点 修饰的属性方法在内存只有一份随着类加载而初始化不要new,可以通过类名直接调用被该类的所…

异或运算实现加密解密

异或运算符^&#xff0c;相同为0&#xff0c;不同为1&#xff08;同0非1&#xff09; 由异或运算法则可知&#xff1a;a ^ a 0&#xff0c;a ^ 0 a 如果c a ^ b&#xff0c;那么a b ^ c&#xff0c;即a ^ b ^ b a&#xff0c;^ 的逆运算仍然是 ^ 利用异或运算的性质&am…

LabVIEW船舶自动识别系统

在现代航海领域&#xff0c;安全高效的船舶自动识别系统对于保障航行安全和提高船舶管理效率非常重要。介绍了利用LabVIEW软件开发的一个船舶自动识别系统&#xff0c;该系统通过先进的数据采集和信号处理技术&#xff0c;显著提升了传统自动识别系统的性能。 这个船舶自动识别…

IAR编译和调试CMS32L051

0 Preface/Foreword 0.1 参考文档 中微半导体BAT系列单片机学习笔记_V1.1.pdf 1 配置方法 1.1 编译工具链添加 CMS对于IAR工具&#xff0c;有一个插件文件&#xff0c;用于安装对应的CMS系列芯片。 工具名称&#xff1a;iar_plug20210926.7z 按照完成之后&#xff0c;可…

电脑监控软件都有哪些?哪款好用?

在当今数字化时代&#xff0c;电脑监控软件已经成为企业和个人用户保障信息安全、管理电脑资源的重要工具。市场上存在多种电脑监控软件&#xff0c;每款软件都有其独特的优点和适用场景。本文将为您介绍几款常见的电脑监控软件&#xff0c;并分析哪款更适合您的需求。 绿虫电…

【windows计算md5】

windows计算md5 使用Windows系统自带的certutil命令。在命令提示符中输入“certutil -hashfile 文件路径 MD5”即可计算文件的MD5值。 例如&#xff0c;要计算D盘根目录下的test.txt文件的MD5值&#xff0c; 可以输入certutil -hashfile D:\test.txt MD5