处理机调度与死锁
1. 处理机调度的基本概念
处理机调度:从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程的并发执行。
1.1 调度的层次
- 高级调度(作业调度)
内存和辅存之间的的调度
外存的后备队列中选择一批作业进入内存
(1) 接纳多少个作业
(2) 接纳哪些作业
- 低级调度(进程调度)
最基本的调度,就绪队列中选取一个进程分配处理机。
就绪队列中选出一个进程,并把其状态改为运行态
(1) 非抢占方式
a.正在执行的进程执行完毕, 或因发生某事件而不能再继续执行。
b.执行中的进程因提出I/O请求而暂停执行。
c.在进程通信或同步过程中执行了某种原语操作,如P操作(wait操作)、Block原语、Wakeup原语等。
(2) 抢占方式
抢占原则:优先权原则,短作业优先原则,时间片原则
- 中级调度
将暂时不运行的进程调至外存等待变为挂起状态,等具备运行条件时将其重新调入内存变为就绪态,在就绪队列等待进程调度。
提高内存的利用率和系统吞吐量。
1.2 调度队列模型
- 仅有进程调度的调度队列模型
- 具有高级和低级调度的调度队列模型
- 同时具有三级调度的调度队列模型
1.3 基本准则
- 面向用户的准则
(1) 周转时间短。
a.周转时间=完成时间-到达时间
b.平均周转时间
c.带权周转时间:作业的周转时间T与系统为它提供服务的时间TS之比
d.平均带权周转时间
(2) 响应时间快。
(3) 截止时间的保证。
(4) 优先权准则。
- 面向系统的准则
(1) 系统吞吐量高。
(2) 处理机利用率好。
(3) 各类资源的平衡利用。
1.4 调度的时机
不能进行进程的调度与切换的情况
- 在处理中断的过程中
- 进程在操作系统内核程序临界区中
- 其他需要完全屏蔽中断的原子操作过程中
2. 调度算法
2.1 先来先服务FCFS和短作业(进程)优先SJ( P )F
- 先来先服务FCFS
算法简单但效率低。
非抢占式算法,对长作业有利,对短作业不利。
有利于CPU繁忙型作业,而不利于I/O繁忙型作业。
- 短作业优先 SJF
抢占式,非抢占式。
优点
SJF算法的平均等待时间,平均周转时间最少
缺点
(1) 该算法对长作业(进程)不利,可能导致长作业(进程)一直不被调度。
(2) 不能考虑作业的紧迫程度。
(3) 作业(进程)的长短是根据用户提供的估计执行时间而定的,不一定能真正做到短作业优先。
2.2 高优先权优先
- 优先权的类型:
(1) 静态优先权
创建进程时已经确定(有的系统优先数越小表示的优先权越高,而有的系统恰恰相反)
(2) 动态优先权
优先权随进程的推进或随其等待时间的增加而改变。
一般情况下进程优先级的设置参照以下原则:
a. 系统进程>用户进程
b. 交互型进程>非交互型进程
c. I/O型进程>计算型进程
- 优先权调度算法:
(1) 非抢占式
主要用于批处理系统,以及一些对实时性要求不严的实时系统中。
(2) 抢占式
常用于要求比较严格的实时系统中,以及对性能要求较高的批处理和分时系统中。
- 高响应比优先调度算法
主要用于作业调度
响应时间=等待时间+服务时间,优先权就相当于响应比Rp
特点
(1) 等待时间相同,服务时间越短响应比越高,对短作业有利。
(2) 要求服务时间相同,等待时间越长响应比越高,即先来先服务。
(3) 长作业等待时间越长响应比越高,等待时间足够长便可获得处理机。
2.3 基于时间片的轮转
- 时间片轮转法
就绪进程按照到达时间排到就绪队列,进程调度程序选择就绪队列的第一个进程执行,即先来先服务原则,但仅能运行一个时间片(几ms到几百ms),使用完一个时间片之后,即使进程并未完成其运行,它也必须释放出处理机给下一个就绪的进程,然后该进程返回到就绪队列的末尾重新排队,等待再次运行。
主要适用于分时系统
进程的切换增大系统开销
时间片的选择要适当,若时间片足够大,便退化为先来先服务调度算法。若时间片很小,处理机在进程间过于频繁的切换,处理机开销大。
- 多级反馈队列调度算法
(1) 设置多个就绪队列,为各个队列赋予不同的优先级。优先权愈高的队列中,为每个进程所规定的执行时间片就愈小。
(2) 一个新进程进入内存后先放入队列,如果在一个时间片结束后未能执行完,调度程序便将它转入第二队列。如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n队列中便采取按时间片轮转的方式运行。
(3) 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行; 仅当第1~(i-1) 队列均空时,才会调度第i队列中的进程运行。
- 多级反馈队列调度算法的性能
(1) 终端型作业用户:短作业优先
(2) 短批处理作业用户:周转时间较短
(3) 长批处理作业用户:不会长期得不到处理
3. 实时调度
3.1 基本条件
- 提供必要的信息
(1) 就绪时间。
(2) 开始截止时间和完成截止时间。
(3) 处理时间。
(4) 资源要求。
(5) 优先级。
- 系统处理能力强
- 采用抢占式调度机制
- 具有快速切换机制
3.2 分类
- 非抢占式调度算法
(1) 非抢占式轮转调度算法。
(2) 非抢占式优先调度算法。
- 抢占式调度算法
(1) 基于时钟中断的抢占式优先权调度算法。
(2) 立即抢占的优先权调度算法。
3.3 常用的几种算法
- 最早截止时间优先(EDF)算法(非抢占调度)
- 最低松弛度优先(LLF)算法
根据任务紧急(或松弛)的程度,来确定任务的优先级。
松弛度=必须完成时间-其本身的运行时间-当前时间
4. 产生死锁的原因和必要条件
4.1 产生死锁的原因
- 竞争资源引起进程死锁
竞争非剥夺性资源
竞争临时性资源
- 进程间推进顺序非法引起死锁
P1保持了资源R1, P2保持了资源R2,当P1运行到P1:Request(R2)时,将因R2已被P2占用而阻塞;当P2运行到P2: Request(R1)时,也将因R1已被P1占用而阻塞,于是发生了进程死锁。
4.2 产生死锁的必要条件
(1) 互斥条件
(2) 请求和保持条件
(3) 不剥夺条件
(4) 环路等待条件
4.3 处理死锁的基本方法
事先预防
(1) 预防死锁。(破坏死锁产生的4个必要条件)
(2) 避免死锁。(用某种方法防止系统进入不安全状态)
(3) 检测死锁。 (通过系统的检测机构)
(4) 解除死锁。 (采取措施)
5. 预防和避免死锁
5.1 预防死锁
- 摒弃"互斥"条件
有些资源不能同时访问,有的场合应该保护互斥性,方法不可行。 - 摒弃“请求和保持”条件
进程在运行前一次性申请完它所需要的全部资源
系统资源严重浪费,可能发生饥饿现象 - 摒弃“不剥夺”条件
已保持不可剥夺资源的进程请求新的资源而得不到满足时,必须释放已经保持的所有资源,待以后需要再重新申请。
增加系统开销降低吞吐量 - 摒弃“环路等待”条件
顺序资源分配法,进程按编号递增顺序请求资源
5.2 避免死锁
5.2.1 系统安全状态
系统安全状态
在避免死锁的方法中,允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次资源分配的安全性。若此次分配不会导致系统进入不安全状态,则将资源分配给进程; 否则,令进程等待。
系统能按某种进程顺序(P1, P2, …,Pn)(称〈P1, P2, …, Pn〉序列为安全序列),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成。
5.2.2 银行家算法避免死锁
- 银行家算法的数据结构
(1) 可利用资源向量Available
(2) 最大需求矩阵Max
(3) 分配矩阵Allocation
(4) 需求矩阵Need
==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) 设置两个向量:
a. 工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work∶=Available;
b. Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]∶=false; 当有足够资源分配给进程时, 再令Finish[i]∶=true。
(2) 从进程集合中找到一个能满足下述条件的进程:
a. 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都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。
6. 死锁的检测与解除
6.1 死锁的检测
死锁检测中的数据结构:资源分配图
(1) 可利用资源向量Available,它表示了m类资源中每一类资源的可用数目。
(2) 把不占用资源的进程(向量Allocation∶=0)记入L表中, 即Li∪L。
(3) 从进程集合中找到一个Requesti≤Work的进程,做如下处理:① 将其资源分配图简化,释放出资源,增加工作向量Work∶=Work+Allocation[i]。 ② 将它记入L表中
(4) 若不能把所有进程都记入L表中, 便表明系统状态S的资源分配图是不可完全简化的。 因此,该系统状态将发生死锁。
6.2 死锁的解除
(1) 剥夺资源。
(2) 撤消进程。
(3) 进程回退。