操作系统3——处理机调度与死锁

本系列博客重点在深圳大学操作系统课程的核心内容梳理,参考书目《计算机操作系统》(有问题欢迎在评论区讨论指出,或直接私信联系我)。


梗概

本篇博客主要介绍操作系统第三章处理机调度与死锁的相关知识。

目录

一、调度基本概念

1.处理机调度层次

2.调度原则与评估标准

二、调度算法

1.先来先服务(FCFS)

2.短作业(进程)优先(SF)调度算法

3.高响应比优先(HRN)调度算法

4.最高优先权(HPF)调度算法 

5.时间片轮转(RR)调度算法

6.多级队列调度算法

7.多级反馈队列调度算法 

三、实时调度

1.时间片轮转调度算法

2.非抢占优先权调度算法

3.基于时间中断的抢占优先权调度算法 

4.立即抢占的优先权调度算法

5.最早开始截止时间优先(EDF)算法

6.最低松驰度优先(LLF)算法

四、多处理机系统调度 - 了解

五、死锁

1.死锁概述

2.预防死锁

3.避免死锁 - 银行家算法

4.死锁的检测与解除


先来道小例题吧:

如果系统只有一个cpu,有两个进程要运行.进程A的运行时间将是1小时,进程B的运行时间是1分钟.那么认为操作系统让哪个进程先运行比较合理?

A.让时间长的进程A先运行

B.让时间短的进程B先运行

C.无所谓,都一样

D.先后无所谓,两个轮流各运行一小会儿最好

E.唉,听说酱油要涨价了

综述:与操作系统的调度策略有关,即更重视优先级还是到来顺序、时长等因素。

一、调度基本概念

调度是对处理机(CPU)资源进行分配。

1.处理机调度层次

处理机调度层次分为高级调度(长程调度/作业调度)、低级调度(短程调度/进程调度)、中级调度(内存调度)不同调度区分主要是运行频率,进程调度最频繁,也是研究的重点,不同调度的架构如下:

  • 高级调度: 决定哪些外存作业调入内存并创建进程与分配资源,即将一个或一批作业从后备状态变为运行状态。
  • 中级调度:决定哪些进程可参与竞争CPU,实际上是实现“挂起”和“激活”操作,主要用于提高内存利用率与系统吞吐率。
  • 低级调度:决定哪个进程可获得CPU,从活动就绪队列中挑选一个进程,将它变为运行态,同时启动CPU执行该进程,是不同系统中必须的调度。

Tips:进程(低级)调度一般有两种方式:

1、非抢占方式:进程获得CPU后,一直执行完成或自动阻塞

2、抢占方式:进程获得CPU后,允许其它进程依据一定的原则抢占CPU资源

(1)时间片原则 (2)优先权原则 (3)短作业(进程)优先原则

具有不同调度层次的调度队列模型如下:

1、仅有低级调度的调度队列模型

每个进程执行时: (1)进程在时间片内已完成,进入完成状态 (2)未完成,放在就绪队列后 (3)因某事件,进入阻塞状态

2、具有高级和低级进程调度的调度队列模型: 

3、具有三级调度的调度队列模型:  

2.调度原则与评估标准

在不同的操作系统中,对调度策略与算法的选择,取决于操作系统的类型与设计目标。

处理及调度算法的共同目标一般是资源利用率、公平性、平衡性、策略强制执行(安全策略)。

Tips:CPU利用率即CPU有效工作时间/CPU有效工作时间+CPU空闲等待时间。

而评估标准一般是不同类型的周转时间,具体如下:

1、周转时间

作业(进程)i从提交(进入时刻)到完成的时间称为该作业的周转时间Ti

Ti = 完成时刻 – 进入时刻

2、平均周转时间:

平均周转时间为n个作业(进程)周转时间的平均值

T=\frac{1}{n}\left[\sum_{i=1}^{n} T_{i}\right]

3、带权周转时间:

作业(进程)周转时间Ti与实际运行时间Tsi之比称为该作业的带权周转时间Wi

W_{i}=\frac{T_{i}}{T_{s i}}

4、平均带权周转时间:

平均带权周转时间为n个作业(进程)带权周转时间的平均值

W=\frac{1}{n}\left[\sum_{i=1}^{n} \frac{T_{i}}{T_{s i}}\right]

而调度原则一般根据对象可以分为两种:

1、面向用户:

周转时间短 响应时间快 截止时间的保证 优先权准则

2、面向系统:

系统吞吐量高 处理机利用率好 各类资源的平衡使用

二、调度算法

调度算法是指根据系统的资源分配策略所规定的资源分配算法

1.先来先服务(FCFS)

核心:选择待调度的作业(进程)最先来的。

作业调度:从后备队列中,选择一个或多个最先进入该队列的作业

进程调度:从就绪队列中,选择一个最先进入该队列的进程,把处理机分配给它,一直运行完或自动阻塞

综述:非抢占方式,优缺点如下:

  • 优点:简单,有利于CPU繁忙型作业(进程),有利于长时间作业(进程)
  • 缺点:对短时作业(进程)不利,对I/O繁忙型作业(进程)不利,对紧迫作业(进程)不利 

2.短作业(进程)优先(SF)调度算法

核心:选择待调度的作业(进程)预估时间最短的。

作业调度:从后备队列中,选择一个或多个估计执行时间最短的作业

进程调度:从就绪队列中,选择一个估计需CPU时间最短的进程,把处理机分配给它

综述: 可以抢占方式和非抢占方式工作,优缺点如下:

  • 优点:有利于短时作业(进程)   在抢占方式中,最短时作业(进程)将以最快的速度完成
  • 缺点:⑴、对长时间作业(进程)不利 ⑵、未考虑作业(进程)的紧迫程度 ⑶、在抢占方式中,最短指总需要时间最短还是剩余时间最短(而且是估计值) ⑷、在抢占方式下,即使一个长作业(进程)正在运行,但也可能会被长时间地延迟

3.高响应比优先(HRN)调度算法

Tips:要求服务时间 = 运行时间 

核心:选择待调度的作业(进程)响应比最高的。

综述:非抢占方式,等待时间相同时,成为SF,运行时间相同时,成为FCFS,实现了较好折中,优缺点如下:

  • 优点:有利于短时作业(进程)   有利于先来者
  • 缺点:每次调度前,必须计算Rp,增加系统开销   未考虑作业(进程)的紧迫程度

4.最高优先权(HPF)调度算法 

核心:选择待调度的作业(进程)优先级最高的。

其中,最高优先权进程调度方式分为非抢占与抢占,简介如下:
1、进程调度的非抢占方式:系统一旦将CPU分配之后,一直到进程执行完成或自动进入阻塞状态

2、进程调度的抢占方式:只要进入就绪队列的进程优先权高于正在CPU上运行现进程的优先权,则将现进程放到就绪队列尾,并运行最高优先权进程

同样,最高优先权优先权设计分为动态与静态,简介如下:

1、静态优先权:

⑴、在作业(进程)被调度之前赋值,之后一直不变

⑵、优先权的取值可根据:作业(进程)类型,对资源的要求,用户要求等

2、动态优先权:

⑴、在作业(进程)被调度之前赋初值

⑵、在作业(进程)运行过程中,动态改变优先权

综述: 可用于作业与进程调度,但动态优先权算法只用于进程调度,抢占方式可用于实时系统,若采用采用非抢占方式 ⑴、优先权只依据到达时间,则变为FCFS ⑵、优先权只依据运行时间,则变为SF ⑶、优先权只依据Rp,则变为HRN,优缺点如下:

  • 优点:可以根据要求,照顾到对系统、用户综合来说最优先的作业(进程)的执行
  • 缺点:优先权的计算可能比较复杂,增加系统开销

5.时间片轮转(RR)调度算法

RR调度算法是一种抢占方式的进程调度算法

RR依据公平服务原则,在一定时间内,为每个进程轮转服务一次

RR每次为一个进程执行一个时间片

时间片长度T是人为确定的,可以等长或不等长

PR调度算法核心流程:

在第n秒(每过一次时间片长度)时,做如下三个判断:(1)队尾入队,(2)下CPU调整队(上一个服务的进程放入队尾),(3)队首入CPU运行

综述: RR用于进程调度,适合于分时系统   时间片越长,越有利于缩短周转时间   如果时间片太长,RR退化为FCFS,优缺点如下:

  • 优点:有利于交互性、事务性进程   有利于I/O繁忙型的进程
  • 缺点:调度开销较大,未考虑实时响应要求

6.多级队列调度算法

为了提高计算机系统的性能,一个系统中可能同时配置几种操作系统

将就绪队列分成多种不同队列(前台轮转就绪队列、后台FCFS就绪队列)

每个进程固定地分属于一个队列

不同队列采用不同的调度算法(前台就绪队列采用RR调度算法,后台就绪队列采用FCFS算法)

只有当前台就绪队列空时,才执行后台队列中的进程

特性:同一计算机系统存在多个OS,优缺点如下:

  • 优点:可以同时兼顾到分时及批量处理任务
  • 缺点:未考虑紧迫性作业或进程 

7.多级反馈队列调度算法 

设置多个就绪队列,并从高到低赋予不同的优先级

每个队列采用RR算法,时间片长度从高优先级到低优先级依次增加(一般加倍)(S1<S2<…<Sn)

算法核心流程如下:

  • 新进程放到最高优先级就绪队列尾部
  • 如果进程在当前就绪队列中执行一次未完成,则插入低一级就绪队列尾部
  • 较高优先级就绪队列全部为空时,才执行后续队列进程
  • 如有更高优先级进程,则将当前进程放在当前就绪队列尾部,转而执行优先级高的进程(回来执行的时候差多少补多少)

综述: 是一种比较好的进程调度算法,能满足各种类型用户的需要,优缺点如下:

  • 优点:可以同时兼顾到实时、分时及批量处理作业(进程)
  • 缺点:调度算法比较复杂,调度开销较大

三、实时调度

实时调度能满足实时任务队截止时间的要求,基本条件如下:

1、提供必要的信息:

(1)就绪时间。 (2) 开始截止时间和完成截止时间。 (3) 处理时间。 (4) 资源要求。 (5) 优先级。

2、系统处理能力强:
假定系统中有m个周期性的硬实时任务,它们的处理时间可表示为Ci,周期时间表示为Pi,则在单处理机情况下,必须满足下面的限制条件(即对任务的平均处理时间 > 平均周期时间): 

\sum_{i=1}^{m} \frac{C_{i}}{P_{i}} \leq 1

对于多处理机系统(如N个),限制如下:

\sum_{i=1}^{m} \frac{C_{i}}{P_{i}} \leq N

3、采用抢占式调度机制:以便高优先权的任务满足对截止时间的要求
4、具有快速切换机制:

 (1) 对外部中断的快速响应能力、 (2) 快速的任务分派能力

1.时间片轮转调度算法

可以满足响应时间在数秒的实时控制,可应用于一般实时系统

2.非抢占优先权调度算法

可以满足响应时间在数百毫秒的实时控制,可用于要求不太严格的实时控制系统

3.基于时间中断的抢占优先权调度算法 

可以满足响应时间在几毫秒到几十毫秒的实时控制,可用于大多数实时控制系统

4.立即抢占的优先权调度算法

可以满足响应时间在毫微秒到几毫秒的实时控制,基本可满足所有实时控制系统要求 

5.最早开始截止时间优先(EDF)算法

根据任务的开始截止时间确定任务的优先级。开始截止时间越早,优先级越高

6.最低松驰度优先(LLF)算法

根据任务的紧急(松驰)程度确定任务的优先级,临界状态(松弛度为0)发生抢占

松驰度=完成截止时间-处理时间-当前时间 

实例:一个实时系统中,有两个周期性实时任务A和B,任务A要求每 20 ms执行一次,执行时间为 10 ms;任务B只要求每50 ms执行一次,执行时间为 25 ms。 应用最低松弛度优先算法调度:

  • 每个任务在自己周期内只执行一次
  • 松弛度为0发生抢占 

四、多处理机系统调度 - 了解

多处理机系统类型一般分为:  (1) 紧密耦合(Tightly Coupted)MPS、 (2) 松散耦合(Loosely Coupled)MPS

而多处理机系统又可划分为(1)对称多处理器系统SMPS(Symmetric MultiProcessor System)、 (2) 非对称多处理器系统

其中对称多处理器系统中的进程分配方式可分为(1)静态分配与(2)动态分配

非对称MPS中的进程分配方式大多采用主—从(Master-Slave)式OS

其进程(线程)调度方式主要是(1)自调度机制、(2)成组调度、(3)专用处理器分配方式。

五、死锁

1.死锁概述

死锁指多个进程因竞争资源而造成的一种僵局,若无外力作用,这些进程都将永远不能再向前进 

产生死锁的原因主要有两个:

1、竞争资源:当两个或以上进程需要两个或以上资源(主要是非剥夺资源或临时性资源

1、可剥夺性资源:某进程获得该类资源后,可被其他进程或系统录夺(如CPU,RAM等) 2、非剥夺性资源:某进程获得该类资源后,其他进程或系统不可剥夺,只能在进程用完后自行释放(如打印机等)

3、临时性资源:由某进程产生,由另一进程临时使用的资源(如信号量)

2、进程推进顺序非法:请求和释放资源的顺序不当 

对于产生死锁的必要条件:

1、互斥条件:请求的资源为临界资源

2、请求和保持条件:申请新资源,保持旧资源

3、不剥夺条件:已获得的资源,在使用完之前,不被外力剥夺

4、环路等待条件:互相等待资源 

而处理死锁的基本方法有:

1、预防死锁:

设置某些限制条件,破坏产生死锁的必要条件中的一个或几个条件

2、避免死锁:

在资源的动态分配过程中,用某种方法,去防止系统进入不安全状态

3、检测死锁:

通过检测机构,及时地检测出死锁的发生及原因,并确定有关的进程和资源

采取措施,解除死锁

4、解除死锁:

剥夺资源或通过撤消进程,收回一些资源。

解除死锁与检测死锁是相互合作的关系。

补充:大多数操作系统对于死锁的策略是忽略(鸵鸟策略),交由用户处理。

2.预防死锁

核心:设置某些限制条件,破坏产生死锁的必要条件中的一个或几个条件

1、摒弃“请求和保持”条件:一次将资源全部分配

  • 优点:简单,易于实现且安全
  • 缺点:资源浪费严重,进程延迟运行

2、摒弃“不剥夺”条件:

当请求的资源得不到满足时,释放已分配的资源

缺点:前期工作全部作废,代价高,反复申请,性能下降

3、摒弃“环路等待”条件:

对资源的申请必须按一定顺序进行

缺点:资源序号需要相对稳定,先获得的资源有可能长期闲置,对用户编程(资源申请时)有限制

4、摒弃“互斥”条件:

分时 虚拟-合并 缓冲

3.避免死锁 - 银行家算法

避免死锁的核心就是动态分配资源前判断是否会让系统进入不安全状态(不安全区,危险区和禁区),若会则令进程等待

安全状态,是指系统能按某种进程顺序(P1, P2, …,Pn)(称〈P1, P2, …, Pn〉序列为安全序列),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成。如果系统无法找到这样一个安全序列,则称系统处于不安全状态。

若不按<P2,P1,P3>安全序列分配,会出现死锁。

避免死锁的主流算法是银行家算法思想。 核心:根据系统是否处于安全状态,来决定分配资源与否。

而对于银行家算法的具体实现主要由以下几个数据结构:

1、可利用资源向量Available:

一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目

2、最大需求矩阵Max:

一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求

3、分配矩阵Allocation:

一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数

4、需求矩阵Need:

一个n×m的矩阵,用以表示每一个进程还需的各类资源数

Need[i,j]=Max[i,j]-Allocation[i,j]

设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

(1) 如果Requesti[j]≤Need[i,j],便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。        

(2) 如果Requesti[j]≤Available[j],便转向步骤(3);否则, 表示尚无足够资源,Pi须等待。

 (3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:

① Available[j]∶=Available[j]-Requesti[j];

② Allocation[i,j]∶=Allocation[i,j]+Requesti[j];

③ Need[i,j]∶=Need[i,j]-Requesti[j];

(4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。 

对于系统整体安全状态的检查,引入安全性算法,核心实现如下:

 (1) 设置两个向量:① 工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work∶=Available; ② Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]∶=false; 当有足够资源分配给进程时, 再令Finish[i]∶=true。

 (2) 从进程集合中找到一个能满足下述条件的进程:          ① Finish[i]=false; ② Need[i,j]≤Work[j]; 若找到, 执行步骤(3), 否则,执行步骤(4)。        

(3) 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:  Work[j]∶=Work[i]+Allocation[i,j];   Finish[i]∶=true;   go to step 2;

  (4) 如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。

假定系统中有五个进程{P0, P1, P2, P3, P4}和三类资源{A, B, C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如图所示:

 一个安全序列样例如下:

银行家算法的缺点如下:

1.很少有进程能够在运行前就知道其所需资源的最大值

2.而且进程数也不是固定的,往往在不断地变化(如新用户登录或退出)

3.原本可用的资源也可能突然间变成不可用(如磁带机可能坏掉)

4.银行家算法的开销较大,实时性不是很好 

4.死锁的检测与解除

死锁的检测主要是对于资源分配图,一般包含如下信息:

1.进程:圆圈 2.资源:方框 3.请求边:由进程指向资源 4.分配边:由资源指向进程

而死锁的检测主要使用死锁定理,核心流程如下:

  • 第一步:先看R1资源,它有三个箭头是向外的,因此它一共给进程分配了3个资源,此时,R1没有空闲的资源剩余。
  • 第二步:再看R2资源,它有一个箭头是向外的,因此它一共给进程分配了1个资源,此时,R2还剩余一个空闲的资源没分配。
  • 第三步:看完资源,再来看进程,先看进程P2,它只申请一个R1资源,但此时R1资源已经用光了,所以,进程P2进入阻塞状态,因此,进程P2暂时不能化成孤立的点。
  • 第四步:再看进程P1,它只申请一个R2资源,此时,系统还剩余一个R2资源没分配,因此,可以满足P1的申请。这样,进程P1便得到了它的全部所需资源,所以它不会进入阻塞状态,可以一直运行,等它运行完后,我们再把它的所有的资源释放。相当于:可以把P1的所有的边去掉,变成一个孤立的点。
  • 第五步:进程P1运行完后,释放其所占有的资源(2个R1资源和1个R2资源),系统回收这些资源后,空闲的资源便变成2个R1资源和1个R2资源,由于进程P2一直在申请一个R1资源,所以此时,系统能满足它的申请。这样,进程P2便得到了它的全部所需资源,所以它不会进入阻塞状态,可以一直运行,等它运行完后,我们再把它的所有的资源释放。相当于:可以把P2的所有的边都去掉,化成一个孤立的点。

Tips:左右箭头只表示申请和分配,未含响应,死锁定义的详解可见:死锁定理与资源分配图化简法_Cuzblind的博客-CSDN博客 

下图是一个存在死锁的例子:

而对于死锁的解除,即(1)剥夺资源,(2) 撤消进程

实用而又简便的方法是: 逐个撤消那些代价最小的进程,或者,使撤消进程的数量最少,直至获得为解除死锁所需要的足够可用的资源。 

若当前运行进程(  )后,系统将会执行进程调度原语. A.执行了一条转移指令 B.要求增加主存空间,经系统调用银行家算法进行测算认为是安全的. C.执行了一条I/O指令要求输入数据 D.执行程序期间发生了I/O完成中断. 

猜你喜欢

转载自blog.csdn.net/weixin_51426083/article/details/131370380