王道操作系统笔记(四)———— 进程同步与互斥

news2025/2/24 6:53:59

文章目录

  • 一、同步与互斥的概念
    • 1.1 同步与互斥的基本概念
    • 1.2 临界资源与共享资源
    • 1.3 独占设备与共享设备
  • 二、实现临界区互斥的基本方法
    • 2.1 软件实现方法
      • 2.1.1 单标志法
      • 2.1.2 双标志先检查法
      • 2.1.3 双标志后检查法
      • 2.1.4 Peterson 算法
      • 2.1.5 软件实现方法总结
    • 2.2 硬件实现方法
      • 2.2.1 中断屏蔽法
      • 2.2.2 硬件指令法
      • 2.2.3 硬件实现方法总结
      • 2.2.4 补充:互斥锁
  • 四、信号量
    • 4.1 整型信号量
    • 4.2 记录型信号量
    • 4.3 信号量实现进程同步、互斥与前驱关系
      • 4.3.1 实现进程同步
      • 4.3.2 实现进程同步
      • 4.3.3 实现前驱关系(多级同步)
      • 4.3.4 同步、互斥和前驱关系总结(★)


一、同步与互斥的概念

  异步性 是指,各并发执行的进程以各自独立的、不可预知的速度向前推进。进程具有 异步性 的特征,因此操作系统要提供 进程同步机制 来解决异步问题。此外,有些资源 一个时间段内只允许一个进程访问,操作系统要使得进程 互斥的访问 来该资源。

1.1 同步与互斥的基本概念

  • 进程同步
    同步,亦称 直接制约关系进程同步 是指在某些时刻为完成某种任务而使得多个进程协调工作而产生的 制约关系。(如:管道通信中,一定是先写在读)

  • 进程互斥
    互斥,亦称 间接制约关系进程互斥 是指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。(如:访问打印机)


1.2 临界资源与共享资源

  • 临界资源
    将一次只允许一个进程使用 的资源称为 临界资源。许多物理设备都属于临界资源,如:打印机、摄像头。

    临界资源的访问过程分成 4 个部分:
     ① 进入区:负责检查是否可进入临界区,若可进入需要上锁。
     ② 临界区进程中访问临界资源的那段代码,又称临界段。
     ③ 退出区:负责解锁。
     ④ 剩余区:代码中其余部分。

  • 共享资源
    将一次允许多个进程同时使用 的资源称为 共享资源。如:输出一行字符。
    进程之间往往 宏观 上同时共享使用该资源,而 微观 上交替使用

  • 两种资源共享方式
    资源共享方式有两种,分别是:互斥共享方式同时共享方式。其中,互斥共享方式 对应 临界资源,同时共享方式 对应 共享资源
    互斥共享方式:一个时间段内 只允许一个进程 访问。
    同时共享方式:允许一个时间段内 可由多个进程 “同时” 访问。

  • 常见的临界资源与共享资源
    临界资源:打印机、共享变量、共享缓冲区、公用队列。
    共享资源:磁盘、非共享变量、可重入的代码。

    共享变量 x 初值等于 1,现假设 x 值代表可用资源数量(如:打印机),当 x = 0 时,进程处于阻塞态。
    正常的执行顺序是:①②③④⑤⑥。当执行到 ④ 时,x=0,进程B处于阻塞态,不会去和A争抢打印机。
    有问题的执行顺序:①②④⑤③⑥。当执行到 ④ 时,由于进程A没有存变量,因此进程B也会申请到打印机的使用权,这会导致打印出错。
    在这里插入图片描述
    综上:共享变量 是 临界资源,非共享变量(如常量) 是 共享资源。

  • 同步机制要遵循的原则

    为了实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则:
     ① 空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
     ② 忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待;
     ③ 有限等待:对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿);
     ④ 让权等待:当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。


1.3 独占设备与共享设备

独占设备 对应 临界资源,共享设备 对应 共享资源 。

  • 独占设备一个时间段只能分配给一个进程,如:打印机。
  • 共享设备一个时间段可同时分配给多个进程,如:磁盘。各进程往往是宏观上同时共享使用设备,而微观上交替使用。

磁盘是共享设备,但在每个时刻(至多能由一个)作业启动它。
解析:共享设备某时间段内可由昨个用户进行访问,但在某一时刻只能有一个作业可以访问。


二、实现临界区互斥的基本方法

2.1 软件实现方法

2.1.1 单标志法

  算法基本思想:设置一个 公用变量 turn,用于指示被允许 进入临界区的进程编号,即若 turn = 0,则允许 P0 进程进入临界区。算法可保证同一时刻只允许一个进程进入临界区,但两个进程必须交替进入临界区。
在这里插入图片描述

  存在问题:若某个进程不再进入临界区,则另一个进程也无法进入临界区,即 每个进程进入临界区的权限只能被另一个进程赋予,违背 “空闲让进” 原则


2.1.2 双标志先检查法

  算法基本思想:设置 一个布尔型数组 flag[],数组中各个元素用来标记各进程想 进入临界区的意愿,比如 flag[0] = ture 意味着 0 号进程 P0 现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有其他进程想进入临界区,如果没有,则把自身对应的标志 flag[i] 设为 true,之后开始访问临界区
在这里插入图片描述

  存在问题:若按照 ①⑤②⑥…. 的顺序执行,P0 和 P1 将会同时访问临界区,违背 “忙则等待” 原则。原因在于,进入区的 检查上锁 两个处理不是 一气呵成先检查后上锁,在 检查后 和 上锁前 可能发生进程切换。


2.1.3 双标志后检查法

  算法基本思想:双标志先检查法的改版,与前一个算法不同,采用 先上锁后检查,来避免上述问题。

在这里插入图片描述

  存在问题:若按照 ①⑤②⑥…. 的顺序执行,P0 和 P1 将都无法进入临界区。因此,双标志后检查法虽然 解决了 “忙则等待” 的问题,但是 又违背了 “空闲让进”和“有限等待” 原则,会因各进程都长期无法访问临界资源而产生 饥饿 现象。两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区。


2.1.4 Peterson 算法

  算法基本思想:结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试 孔融让梨(谦让),做一个有礼貌的进程。进程在进入区要做的步骤: ① 主动争取 ② 主动谦让 ③ 检查对方是否也想使用,且最后一次是不是自己说了客气话
在这里插入图片描述
  存在问题:Peterson 算法用软件方法解决了进程互斥问题, 遵循 “空闲让进”、“忙则等待”、“有限等待” 三个原则,但是依然 未遵循 “让权等待” 的原则。


2.1.5 软件实现方法总结

在这里插入图片描述


2.2 硬件实现方法

硬件实现方法实际上以硬件的方式将检查和上锁绑在一起。

2.2.1 中断屏蔽法

  中断屏蔽法利用 “开/关中断指令” 实现,其与原语的实现思想相同,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个进程同时访问临界区的情况。

在这里插入图片描述
优点: 简单、高效
缺点: 不适用于多处理机只适用于 OS内核进程,不适用于用户进程。(因为开/关中断指令只能运行在内核态,这组指令如果能让用户随意使用会很危险)

注意区分原语与原子操作:
原语是一种特殊程序,执行中不可中断,由开/关中断指令实现。
原子操作是一种执行过程,执行期间一气呵成,不可中断。


2.2.2 硬件指令法

  TestAndSet 指令,简称 TS 指令,也称 TestAndSetLock 指令,或 TSL 指令。TSL指令是 原子操作,执行过程中不可被中断。 以下是用C语言描述的逻辑:

在这里插入图片描述
相比软件实现方法,TSL 指令把 上锁和检查操作 用硬件的方式变成了一气呵成的 原子操作
优点: 实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞。适用于多处理机环境
缺点: 不满足 “让权等待” 原则,暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致 忙等


  Swap 指令,也称 Exchange 指令,或简称 XCHG 指令。Swap 指令是 原子操作,其用硬件实现的,执行的过程不允许被中断,只能一气呵成。以下是用C语言描述的逻辑:

在这里插入图片描述
逻辑上来看 Swap 和 TSL 并无太大区别,都是先记录下此时临界区是否已经被上锁(记录在 old 变量上),再将上锁标记 lock 设置为 true,最后检查 old,如果 old 为 false 则说明之前没有别的进程对临界区上锁,则可跳出循环,进入临界区。Swap 指令优点缺点和TSL指令相同。


2.2.3 硬件实现方法总结

在这里插入图片描述


2.2.4 补充:互斥锁

  解决 临界区 最简单的工具就是 互斥锁 (mutex lock)。一个进程在进入临界区时应 获得锁,在退出临界区时 释放锁 。函数 acquire() 获得锁,而函数 release()释放锁。
  每个互斥锁有一个布尔变量 available,表示锁是否可用。如果锁是可用的,调用 acqiure()会成功,且锁不再可用。当一个进程试图获取不可用的锁时,会被阻塞,直到锁被释放。acquire() 或 release() 的执行必须是 原子操作,因此 互斥锁通常采用硬件机制来实现
在这里插入图片描述

优点: 等待期间不用切换进程上下文,多处理器系统中,若上锁的时间短,则等待代价很低。当多个进程共享同一 CPU时,就浪费了CPU 周期。因此,互斥锁通常用于多处理器系统,一个线程可以在一个处理器上等待,而不影响其他线程的执行,并快速释放临界区。

缺点:不满足 “让权等待” 原则。当有一个进程在临界区中,任何其他进程在进入临界区时必须连续循环调用 acquire(),因此会发生 忙等待


四、信号量

  用户进程可以通过使用操作系统提供的 一对原语 来对 信号量 进行操作,从而很方便的实现了进程互斥、进程同步。信号量其实就是一个变量 ,可以用一个信号量来表示系统中某种资源的数量,比如:系统中只有一台打印机,就可以设置一个初值为 1 的信号量。
  一对原语:wait(S) 原语和 signal(S) 原语,可以把原语理解为函数,函数名分别为 wait 和 signal,括号里的信号量 S 其实就是函数调用时传入的一个参数。wait(S) 原语和 signal(S) 原语也可记为P(S)、V(S)

4.1 整型信号量

整型信号量被定义为一个用于标识资源数目的整型信号量。wait(S)、signal(S)可描述为:

在这里插入图片描述
wait(S) 原语,“检查”和“上锁”一气呵成,避免了并发、异步导致的问题。以申请使用打印机举例:
在这里插入图片描述

存在的问题: 不满足 “让权等待” 原则,会发生 忙等

信号量机制与中断屏蔽法的区别:
① 中断屏蔽法:关中断、临界区、开中断整个执行过程是一个原子操作。
② 信号量机制:wait(S)与signal(S)是两个原子操作。

注:由于PV操作是原语,原语是由特权指令开关中断实现,因此也不适合与用户级线程。


4.2 记录型信号量

  记录型信号量不存在 忙等 现象的进程同步机制。除需要一个用于代表资源数目的整型信号量 value 以外,再增加一个 进程链表 L,用于链接所有等待该资源的进程。

在这里插入图片描述
例:某计算机系统中有1台打印机,则可在初始化信号量 S 时将 S.value 的值设为 1,队列 S.L 设置为空。
在这里插入图片描述

① CPU 为 P0 服务,S.value --,值为 0,P0开始使用打印机。
② CPU 为 P1 服务,S.value --,值为 -1,无资源执行 block 原语( wait原语 )。阻塞队列( P1 ),S.value = -1 说明有1个进程在等待资源。
③ CPU 为 P2 服务,S.value --,值为 -2,无资源执行 block 原语。阻塞队列( P1→P2 ),S.value = -2 说明有2个进程在等待资源。
④ CPU 为 P0 服务,S.value ++,S.value = -1 ≤ 0,说明有进程在等待该资源。因此应调用 wakeup 原语(signal原语)唤醒等待队列中的第一个进程P1,将释放资源给 P1,P1从阻塞态变为就绪态,等待被 CPU 服务(CPU顺序执行)。阻塞队列( P2 )
⑤ CPU 为 P1 服务,P1 使用完打印机,S.value ++,S.value = 0,调用 wakeup 原语唤醒 P2。阻塞队列()。
⑥ CPU 为 P2 服务, P2是用完打印机,S.value ++,S.value = 1。

注:考试中出现 P(S)、V(S) 的操作,除非特别说明,否则默认 S 为记录型信号量。


4.3 信号量实现进程同步、互斥与前驱关系

4.3.1 实现进程同步

  设 S 为实现进程 P1、P2 互斥的信号量,由于只允许一个进程进入临界区,所以 S 的初值应设为 1。然后把临界区置于 P(S) 和 V(S) 之间,进入区之前申请资源(P操作),退出区之前释放资源( V操作 ),即可实现两个进程对临界资源的互斥访问。
在这里插入图片描述

用信号量实现进程互斥:
① 分析并发进程的关键活动,划定临界区(如:对临界资源打印机的访问就应放在临界区)
设置互斥信号量 mutex,初值为 1(即可用资源数为1,理解为:进入临界区的名额)
在进入区 P(mutex) —— 申请资源
在退出区 V(mutex) —— 释放资源

注:对 不同的临界资源 需要设置 不同的互斥信号量P、V操作必须成对出现


4.3.2 实现进程同步

  设 S 为实现进程 P1、P2 同步的信号量,S 的初值应设为 0。只有当前一个进程释放资源后( V操作 ),后一个进程才可申请资源( P操作)。

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

用信号量实现进程同步:
① 分析什么地方需要实现同步关系,即必须保证一前一后(在两个进程中)
设置同步信号量 S,初始为 0
在 “前操作” 之后执行 V(S)
在 “后操作” 之前执行 P(S)


4.3.3 实现前驱关系(多级同步)

前驱关系本质上是 多级同步 的问题,每一对前驱关系都需要保证 一前一后 的操作。

下图是一个前驱图,其中 S1, S2, S3, … ,S6 是进程 P1, P2, P3,…, P6 中的程序段,这些程序段要求按如下前驱图所示的顺序来执行:
① 要为每一对前驱关系各设置一个同步信号量
② 在“前操作”之后对相应的同步信号量执行 V 操作
③ 在“后操作”之前对相应的同步信号量执行 P 操作

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


4.3.4 同步、互斥和前驱关系总结(★)

在这里插入图片描述
注:互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少。

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

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

相关文章

【电子通识】查找硬件学习资料的方法

做为一名硬件工程师,在工作中会经常遇到一些问题,这些问题最开始可能也并不知道是什么原因。对于这些异常现象,我们可能需要深入去了解电路原理或器件特性等方式,从原理上理解并解决。当再次遇到相同或相似的问题时,我…

Python爬虫2--数据解析方法:bs4库的使用和案例

目录标题数据解析1、BeautifulSoup库1.1 BeautifulSoup库入门1.1.1 BeautifulSoup类的基本元素:1.1.2 基于bs4库的HTML内容遍历方法1.1.3 基于bs4库的HTML格式化和编码1.2 信息组织和提取方法1.2.1 信息标记的三种形式:xml,json,yaml1.2.2 三种信息标记形…

360数据恢复如何操作?360安全卫士恢复误删文件的方法(详解)

3 60安全 卫士属于一款杀毒软件,这是很多人都知道的事情。但是你知道吗?3 60安全 卫士还有一个免费功能,就是文件恢复功能。 当文件被误删,电脑回收站又找不到,你可以尝试通过3 60里面的文件恢复功能来进行数据恢复。…

Leetcode:62. 不同路径、63. 不同路径 II(C++)

目录 62. 不同路径 问题描述: 实现代码与解析: 深度优先(超时): 原理思路: 动态规划: 原理思路: 数学方法: 原理思路: 63. 不同路径 II 问题描述&…

AcWing蓝桥杯AB组辅导课09、复杂DP

文章目录前言一、复杂DP例题例题1:AcWing 1050. 鸣人的影分身(线性dp)分析题解:DP例题2:AcWing 1047. 糖果(背包问题变形)分析题解:DP(01背包问题变形)例题3&…

静态库与动态库的生成与使用

一、库文件 预编译——>编译——>汇编——>链接(使用库)——>可执行文件 二、生成库:把大量的已经实现的代码打包起来 生成动态库: 1、将源码遍历汇编生成二进制指令 gcc -fPIC -c child.c -o child.o 2、将所有二进…

即时通讯开发之详解TCP/IP中的UDP 协议

UDP 是传输层协议,和 TCP 协议处于一个分层中,但是与 TCP 协议不同,UDP 协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议。UDP 协议头2.1UDP 端口号由于很多软件需要用到 UDP 协议,所以 UDP 协议必须通过某个标志用以区分不同的程序所需要的数据包。端口号的功能…

C 语言零基础入门教程(二十一)

C 头文件 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。 在程序中要使用头文件,需要使用 C 预处理指令 #include 来引用它。前…

Linux | 编辑器gcc/g++的使用【动静态库的认识】

文章目录一、对程序的认知 && 初识gcc1、程序是如何诞生的?2、gcc的初步认识3、如何使用gcc二、gcc逐步分析程序的翻译环境1、预编译【进行宏替换】2、编译【C语言——>汇编语言】3、汇编【汇编语言——>可重定位目标二进制文件】4、链接【生成可执行…

一篇文章学会写SQL

本篇文章主要讲如何写SQL,虽然我在之前有篇文章中写到过数据库的操作和概念,其中有讲到数据库和表的操作语句以及有哪些函数和查询关键字(本篇不赘述),但毕竟理解概念和会实践书写是两码事。。 身为一名测试人员&#…

证明:lim (x->0+) x^x=1

原式:lim⁡x→0xx\lim _{x\to 0^{}} {x^{x}}x→0lim​xx 根据公式1:u(x)v(x)eu(x)ln⁡v(x)u(x)^{v(x)}e^{u(x)\ln v(x)}u(x)v(x)eu(x)lnv(x)则原式可以化为lim⁡x→0exln⁡x\lim _{x\to 0^{}} e^{x \ln x}x→0lim​exlnx 接下来利用倒代换进行进一步计算。&#xff…

【USB】USB video class (UVC)相关概念学习

UVC协议 IAD 全称Interface Association Descriptor This is used to describe that two or more interfaces are associated to the same function. An ‘association’ includes two or more interfaces and all of their alternate setting interfaces. IAD用来描述由两个…

一次JVM垃圾收集全过程

目录 JVM堆内存分配 JVM垃圾收集完整过程(带图解) 在介绍垃圾收集过程之前,有必要先对JVM堆内存做一个回顾,因为讲垃圾收集主要针对的是堆内存。 JVM堆内存分配 在JDK1.8之前,JVM堆内存主要分为新生代、老年代和永…

Kafka和Flink双剑合璧,Confluent收购Immerok引起业内广泛讨论

2023年开年开源界就出了一个大新闻,1月6日Kafka的商业化公司Confluent创始人宣布签署了收购 Immerok 的最终协议,而Immerok是一家为 Apache Flink 提供完全托管服务的初创公司,其创始团队正是Flink的创始团队。 无论是Kafka还是Flink&#x…

MQ 消息丢失、重复、积压问题,如何解决?

引入 MQ 消息中间件最直接的目的是:做系统解耦合流量控制,追其根源还是为了解决互联网系统的高可用和高性能问题。 系统解耦:用 MQ 消息队列,可以隔离系统上下游环境变化带来的不稳定因素,比如京豆服务的系统需求无论如…

你安全吗?丨生活中常见的黑产行为有哪

作者丨黑蛋电视剧《你安全吗?》我也追完了,到了终结篇。在结尾,网安黑产头子马平川终于因为陷害秦淮攻击虎迫系统被查出来就是虎迫内奸,随后也被一系列证据指出饮料厂等薅羊毛事件背后都有马平川的影子:今天我们就来聊…

python基础学习--数据类型、语句、函数

python的语法比较简单,采用缩进形式,如下: 在这里# print absolute value of an integer: a 100 if a > 0:print(a) else:print(-a)插入代码片以“#”开头的语句是注释。 注意:python是大小写敏感的,如果先写错了…

在线 OJ 项目(二) · 操作数据库 · 设计前后端交互的 API · 实现在线编译运行功能

一、操作数据库前的准备二、封装操作数据库数据的相关操作三、设计前后端交互的 API四、实现在线编译运行功能一、操作数据库前的准备 设计数据库表 我们需要对数据库中存储的题目进行操作. 创建一个 “题目表” oj_table 题目的序号 id. 作为题目表的自增主键。 标题 title.…

Android之常见的使用技巧

文章目录1.全局获取Context的技巧2.使用Intent传递对象Serializable方式Parcelable方式3.定制自己的日志工具4.深色主题5.Java和Kotlin代码之间的转换1.全局获取Context的技巧 在Android中,你会发现有很多地方都需要用到Context,例如:弹出To…

设计模式在项目中的运用

一、如何管理庞大而复杂的项目开发?1、从设计原则和思想的角度来看,如何应对庞大而复杂的项目开发?① 封装与抽象:“一切皆文件”:封装了不同类型设备的访问细节,抽象为统一的文件访问方式,更高层的代码就能…