王道操作系统笔记———— 进程同步与互斥
Posted Xiu Yan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了王道操作系统笔记———— 进程同步与互斥相关的知识,希望对你有一定的参考价值。
文章目录
一、同步与互斥的概念
异步性 是指,各并发执行的进程以各自独立的、不可预知的速度向前推进。进程具有 异步性 的特征,因此操作系统要提供 进程同步机制 来解决异步问题。此外,有些资源 一个时间段内只允许一个进程访问,操作系统要使得进程 互斥的访问 来该资源。
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,同步信号量的初始值要看对应资源的初始值是多少。
以上是关于王道操作系统笔记———— 进程同步与互斥的主要内容,如果未能解决你的问题,请参考以下文章
操作系统王道考研 p17-19 进程同步与互斥进程互斥的软硬件实现方法
操作系统 王道考研2019 第二章:进程管理 -- 进程同步进程互斥(临界资源)实现临界区互斥的基本方法(软(单/双 标志Peterson )硬件(中断屏蔽TSSwap))饥饿
操作系统 王道考研2019 第二章:进程管理 -- 信号量机制(整型 / 记录型信号量)原语P / V操作用信号量机制实现进程互斥同步前驱关系