2.3_5 用信号量实现互斥、同步、前驱关系

news2024/11/25 2:40:37

文章目录

  • 2.3_5 用信号量实现互斥、同步、前驱关系
    • (一)信号量机制实现进程互斥
    • (二)信号量机制实现进程同步
    • (三)信号量机制实现前驱关系
  • 总结

2.3_5 用信号量实现互斥、同步、前驱关系

image-20240304202713079

  我们之前学习了进程互斥的几种软件实现方式、硬件实现方式,但是这些实现方式都有一个共同的缺点——没有办法实现“让权等待”这一原则。

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

  所以,信号量机制是一种更先进的解决方式。

  注:要注意理解信号量背后的含义,不要死盯着代码。一个信号量对应一种资源

  信号量的值 = 这种资源的剩余数量。信号量的值如果小于0,说明此时有进程在等待这种资源。

  P(S) —— 申请一个资源S,如果资源不够就阻塞等待

  V(S) —— 释放一个资源S,如果有进程在等待该资源,则唤醒一个进程

(一)信号量机制实现进程互斥

  1.分析并发进程的关键活动,划定临界区。(即:哪段代码是用于访问临界资源的)

  如:对临界资源——打印机的访问,就应放在临界区。

  2.设置互斥信号量mutex,初值为1

  一个进程在进入临界区之前,需要对mutex执行P()操作;在执行完临界区之后,需要对mutex执行V()操作。以此来完成对临界区代码的互斥访问。

  我们之前说过,信号量表示的就是某种临界资源,而mutex这个信号量,我们可以理解为“进入临界区的名额”这种资源。

  mutex初值为1,就是表示刚开始时,可以进入临界区的名额只有1个。

  而某个进程执行P(mutex)其实就是在表达“想要申请一个进入临界区的名额”。而这种资源如果还有剩余的话,这个进程就可以顺利进入临界区。此时如果还有另一个进程也想要P(mutex),那么它的申请就得不到满足,它必须阻塞等待。直到第一个进程使用完临界区之后,执行V(mutex)归还这个名额,才可以把第二个进程唤醒。

  通过这种方式——对mutex进行P、V操作,就实现了对临界区的互斥访问。

  3.在进入区P(mutex)——申请资源

  4.在退出区V(mutex)——释放资源

image-20240304204623821

  注意1:我们若想定义一个记录型信号量,则只需像semaphore mutex = 1;这样简单定义一下即可。如果题目中没有特别要求,则不需要再把semaphore具体的结构体定义给完整写出(如下)。当然,你自己要会写。

/* 记录型信号量的定义 */
typedef struct {
    int value;			//剩余资源数
    struct process *L;	//等待队列
}

  将信号量定义为记录型信号量,即表示这个信号量本身就是带有排队、阻塞、唤醒等一系列功能的,因此也不会产生“忙等”问题。

  注意2:对不同的临界资源需要设置不同的信号量

image-20240304205131937

  比如此时系统中,P1、P2进程需要访问打印机这种临界资源;而P3、P4进程需要访问摄像头这种临界资源。那在这种情况下,我们要给访问打印机的临界区设置一个信号量mutex1,给访问摄像头的临界区设置另一个信号量mutex2

  注意3P、V操作必须成对出现。缺少P(mutex)就不能保证临界资源的互斥访问。缺少V(mutex)会导致资源永不被释放,等待进程永不被唤醒。

(二)信号量机制实现进程同步

  进程同步:要让各并发进程按要求有序地推进。

image-20240304205825104

  比如说有P1、P2这两个进程,当它们在系统当中并发地运行的时候,由于系统的环境很复杂,所以操作系统在调度的时候,有可能是P1先上处理机运行,也有可能是P2先上处理机运行……

  比如,P2先上处理机运行了代码4、代码5,而此时它的时间片用完了,又切换到P1,P1上处理机运行了代码1、代码2,之后它的时间片也用完了,又切换到P2,P2上处理机运行了代码6……

  总之,由于这两个进程在系统中是并发地运行的,因此它们之间代码执行的先后顺序是我们不可预知的。而有的时候我们又必须让这些代码的执行顺序按照我们想要的那种方式进行。

  例如,P1、P2并发执行,由于存在异步性,因此二者交替推进的次序是不确定的。

  若P2的代码4要基于P1的代码1和代码2的运行结果才能执行,那么我们就必须保证代码4一定是在代码2之后才会执行。

  这就是所谓的进程同步问题。即,让本来异步并发的进程互相配合,有序推进。


用信号量实现进程同步

  1.分析什么地方需要实现“同步关系”,即必须保证“一前一后”执行的两个操作(或两句代码)。

  2.设置同步信号量S,初始为0

image-20240304210554559

  如图,以进程P1、P2为例。

  如果代码4必须在代码2之后执行,那么P2需要在代码4之前对S这个信号量执行一个P()操作,而P1需要在代码2之后对S这个信号量执行一个V()操作。

分析1

  若P1先上处理机运行,执行了代码1、代码2、V(S),那么此时S=1

  之后,再切换到P2上处理机运行,此时,P2进程执行P(S)时就可以顺利运行,并不会被阻塞,从而正常执行代码4

分析2

  若P2先上处理机运行,则当它执行P(S)时就会被阻塞,从而没办法继续向下运行。

  而直到P1上处理机运行,运行了代码1、代码2、V(S)之后,才会唤醒此时正在等待信号量S的进程,即唤醒P2。

  若先执行到V(S)操作,则S++后S=1。之后当执行到P(S)操作时,由于S=1,表示有可用资源,会执行S–,S的值变为0,P2进程不会执行block原语,而是继续往下执行代码4。

  若先执行到P(S)操作,由于S=0,S–后S=-1,表示此时没有可用资源,因此P操作中会执行block原语,主动请求阻塞。之后当执行完代码2,继而执行V(S)操作,S++,使S变回0,由于此时有进程在该信号量对应的阻塞队列中,因此会在V操作中执行wakeup原语,唤醒P2进程。这样P2就可以继续执行代码4了。

理解

  信号量S代表某种“资源”,刚开始是没有这种资源的。P2需要使用这种资源,而又只能由P1产生这种资源。这样就实现了进程之间的同步关系。

  此外,我们将该信号量初值设为0,表示刚开始这种资源是没有的。而只有执行“前操作”之后释放了一个这种资源(“前V”),执行“后操作”之前申请这种资源才能顺利得到(“后P”)。否则,“后操作”就会被阻塞,而即使是“后操作”被阻塞的状态下,也只有“前操作”之后的V()能够将其唤醒。——至此,我们便使用信号量机制实现了进程同步。

image-20240304211703294

  3.在“前操作”之后执行V(S)

  4.在“后操作”之前执行P(S)

  口诀:前V后P。

  例如,代码4必须在代码2之后执行,因此代码2是“前操作”、代码4是“后操作”。因此,我们需要在代码2之后执行一个V(),在代码4之前执行一个P()。

(三)信号量机制实现前驱关系

  是一种更复杂的进程同步问题。

image-20240304212704031

  进程P1中有句代码S1,P2中有句代码S2,P3中有句代码S3……P6中有句代码S6。

  这些代码要求按照如上图所示的顺序来执行,即,S1执行完后,S2、S3才能执行;S2执行完后,S4、S5才能执行;S3、S4、S5执行完后,才能执行S6。

  现在的问题是,如何使用信号量机制解决这么复杂的进程同步问题。

  在这个前驱图中,其实每一对前驱关系(即每一条箭头)都是一个进程同步问题(需要保证一前一后的操作)。因此,

  1.要为每一对前驱关系各设置一个同步信号量

  注:同步信号量的初值为0。因为,这种资源必须刚开始是没有的,必须等“前操作”执行完后释放一个该信号量,“后操作”才能顺势执行,从而实现同步关系。

  2.在“前操作”之后对相应的同步信号量执行V操作

  3.在“后操作”之前对相应的同步信号量执行P操作

  对于S1 ---> S2这个同步关系而言,由于S1执行之后,S2才能执行,因此我们要在“前操作”,即S1之后执行一个V(a);而在“后操作”,即S2之前执行一个P(a)。

  其它的同步关系也都同理,按照前V后P来执行即可。

image-20240304213153184

image-20240304213424575

  经过这样的分析,对于这么复杂的同步关系,我们也可以很轻松的实现它们。

检验:这样的P、V操作,是否真的能正确实现如图所示的前驱关系?

  例如,先让P5上处理机运行,会由于P(d)而发生阻塞。而之后,尽管能够执行V(d)的进程P2上处理机运行,但是P2也会由于P(a)而发生阻塞……最终,除非P1先上处理机运行,执行V(a)之后,S2才有可能执行,进而S5才有可能执行……

总结

image-20240304213955900

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

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

相关文章

MySQL学习Day25——数据库其他调优策略

一、数据库调优的措施: 1.调优的目标: (1)尽可能节省系统资源,以便系统可以提供更大负荷的服务 (2)合理的结构设计和参数调整,以提高用户操作的响应速度 (3)减少系统的瓶颈,提高MySQL数据库整体的性能; 2.如何定位调优:用户的反馈、日志…

基于Springboot的无人智慧超市管理系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的无人智慧超市管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系…

微软多兴趣召回:Octopus

Octopus: Comprehensive and Elastic User Representation for the Generation of Recommendation Candidates 背景: 多兴趣通道(channel)结构的多兴趣召回模型在兴趣通道数量上面存在两个问题 兴趣通道较少,不能充分学习到用户的多个兴趣。兴趣通道较…

力扣hot9---滑动窗口

题目: 先记录一下(没想到有生之年,还能):其实还能优化,后面会讲述优化思路 思路: 滑动窗口的大小就是固定的,就是len_p。那么依次将窗口从s的最左端向右滑动。在当下的窗口中&#x…

鸿蒙开发就业前景以及发展方向分析~

鸿蒙操作系统作为华为公司自主研发的操作系统,已经成为当下炙手可热的话题。作为一个全新的操作系统,鸿蒙开发为IT行业带来了巨大的就业机会。本文将围绕鸿蒙开发的就业前景以及发展方向展开讨论。 一、鸿蒙开发就业前景 随着鸿蒙操作系统的发布&#…

Windows快速删除大量文件

直接上命令 rmdir 磁盘:\文件夹名字\ /s /q /S 表示除目录本身外,还将删除指定目录下的所有子目录和文件。 /Q 表示安静模式,删除时不需要经过确认。 特别是vue项目中的node_modules,删除贼快!

【代码随想录算法训练营Day34】860.柠檬水找零;406.根据身高重建队列;452.用最少数量的箭引爆气球

❇️Day 34 第八章 贪心算法 part04 ✴️今日任务 860.柠檬水找零406.根据身高重建队列452.用最少数量的箭引爆气球 ❇️860.柠檬水找零 本题看上好像挺难,其实挺简单的,大家先尝试自己做一做。题目链接:https://leetcode.cn/problems/lem…

10W 音频功率放大电路芯片TDA2003,可用于汽车收音机及收录机中作音频功率放大器,内部具有短路保护和过热保护等功能

TDA2003 用于汽车收音机及收录机中作音频功率放大器。 采用 TO220B5 封装形式。 主要特点: ⚫ 内部具有短路保护和过热保护。内部具有地线开路、电源极性接 反和负载泄放电压反冲等保护电路。 ⚫ 输出电流大。 ⚫ 负载电阻可低至 1.6 。 …

【短时交通流量预测】基于单层BP神经网络

课题名称:基于单层BP神经网络的短时交通流量预测 版本时间:2023-04-27 代码获取方式:QQ:491052175 或者 私聊博主获取 模型简介: 城市交通路网中交通路段上某时刻的交通流量与本路段前几个时段的交通流量有关&…

Redis核心数据结构之SDS(一)

数据结构与对象 简单动态字符串 概述 Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,简称C字符串),而是自己构建了一种名为简单动态字符串(Simple Dynamic String, SDS)的后向类型,并将SDS用作Redis的默认字符串表示。在…

算法比赛|赛制介绍| ACM, IOI赛制, OI赛制

&#x1f525;博客介绍&#xff1a; 27dCnc &#x1f3a5;系列专栏&#xff1a; <<数据结构与算法>> << 算法入门>> << C项目>> &#x1f3a5; 当前专栏: << 算法入门>> 专题 : 数据结构帮助小白快速入门算法 &#x1f4…

spring boot 字典使用,使用element-ui + vue

数据库表设计 type为1则代表字典的类型 type为2则是下拉框显示的值 id是雪花算法自动生成的 前端设计 基于vue-fast2设计 使用element-ui 异步获取数据 // 获取数据列表getDataList () {this.dataListLoading truethis.$http({url: this.$http.adornUrl(/sys/dict/list)…

C++ 模拟OJ

目录 1、1576. 替换所有的问号 2、 495. 提莫攻击 3、6. Z 字形变换 4、38. 外观数列 5、 1419. 数青蛙 1、1576. 替换所有的问号 思路&#xff1a;分情况讨论 ?zs&#xff1a;左边没有元素&#xff0c;则仅需保证替换元素与右侧不相等&#xff1b;z?s&#xff1a;左右都…

C语言:结构体(自定义类型)知识点(包括结构体内存对齐的热门知识点)

和黛玉学编程呀&#xff0c;大家一起努力呀............. 结构体类型的声明 回顾一下 struct tag { member-list; }variable-list; 创建和初始化 我们知道&#xff0c;在C语言中&#xff0c;对于一些数据是必须初始化的&#xff0c;但是结构体怎么创建并且初始化呢&#xff1…

绘图机器 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 绘图机器的绘图笔初始位置在原点&#xff08;0, 0&#xff09;&#xff0c;机器启动后其绘图笔按下面规则绘制直线&#xff1a; 1&#xff09;尝试沿着横向坐标轴…

基于51单片机的智能睡眠呼吸检测系统[proteus仿真]

基于51单片机的智能睡眠呼吸检测系统[proteus仿真] 呼吸检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的智能睡眠呼吸检测系统[proteus仿真] 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文…

【NR 定位】3GPP NR Positioning 5G定位标准解读(五)

前言 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;二&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位…

远程调用--webClient

远程调用webClient 前言1、创建webClient2、准备数据3、执行请求4、接收返回响应到的数据整体代码 前言 非阻塞、响应式HTTP客户端 1、创建webClient WebClient client WebClient.create();2、准备数据 Map<String,String> params new HashMap<>();params.pu…

【Python】Python教师/学生信息管理系统 [简易版] (源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

#WEB前端

1.实验&#xff1a;vscode安装&#xff0c;及HTML常用文本标签 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; &#xff08;1&#xff09;网页直接搜索安装vscode &#xff08;2&#xff09;打开vscode&#xff0c;在下图分别安装以下插件&#xff1a; Html Css Support …