目录
- 一、调度层次和调度算法目标
- 1.1调度层次
- 1.1.1高级调度
- 1.1.2低级调度
- 1.1.3中级调度
- 1.2调度算法目标
- 1.1调度层次
- 二、作业调度
- 2.1概念
- 2.2先来先服务调度算法FCFS
- 2.3短作业优先调度算法SJF
- 2.4高响应比优先调度算法HRRN
- 三、进程调度
- 3.1进程调度的任务、机制、方式
- 3.2时间片轮转调度算法
- 3.3优先级调度算法
- 3.4多级反馈队列调度算法
- 四、死锁
- 4.1死锁的概念
- 4.1.1资源问题
- 4.1.2死锁的定义、必要条件和处理方法
- 4.2死锁预防
- 4.2.1破坏“请求和保持”条件
- 4.2.2破坏“不可抢占”条件
- 4.2.3破坏“循环等待”条件
- 4.3死锁避免
- 4.3.1系统安全状态
- 4.3.2银行家算法
- 4.4死锁检测与解除
- 4.4.1死锁检测
- 4.4.2死锁解除
- 4.1死锁的概念
一、调度层次和调度算法目标
1.1调度层次
1.1.1高级调度
又称长程调度或作业调度
调度对象是作业
主要功能:根据某种算法,决定将外存上处于后备队列中的哪几个作业调入内存,为其创建进程、分配必要资源并放入就绪队列
主要用于多道批处理系统
作业调度往往发生在一批作业以运行完毕并退出系统,又需要重新调入一批作业进入内存时
1.1.2低级调度
又称短程调度或进程调度
主要功能:根据某种算法,决定就绪队列中的哪个进程应获得处理器,并由分派程序将处理器分配给选中的进程
多道批处理、分时、实时三种OS都必须设置
1.1.3中级调度
又称内存调度
主要功能:把暂时不能运行的进程调至外存等待,当它们具备运行条件且内存有空闲时再重新调回内存,并修改其状态为就绪状态,挂在就绪队列上等待
1.2调度算法目标
1、调度算法的共同目标
- 资源利用率:CPU利用率=CPU有效工作时间/(CPU有效工作时间+CPU空闲等待时间)
- 公平性:诸进程获得合理的CPU时间,不会发生进程饥饿现象
- 平衡性:使系统中的CPU和各种外部设备都能经常处于忙碌状态
- 策略强制实行:即使会造成某些工作的延迟
2、批处理系统的目标
- 平均周转时间短(从作业被提交给系统开始,到作业完成为止的时间间隔)
- 系统吞吐量(单位时间内系统完成的作业数)高
- 处理器利用效率高
3、分时系统的目标
- 响应时间快(从用户通过键盘提交一个请求开始,直到屏幕显示出处理结果为止的时间间隔)
- 均衡性
4、实时系统的目标
- 截止时间的保证:任务开始执行或必须完成的最迟时间
- 可预测性
二、作业调度
2.1概念
作业:不仅包含通常的程序和数据,还应配有一份作业说明书
批处理系统中以作业为基本单位从外存调入内存
作业步:在作业运行期间,每个作业必须经过若干个相对独立,又相互关联的顺序加工步骤才能得到结果,每个加工步骤称为一个作业步
主要任务:根据作业控制块中的信息,检查系统中的需要能否满足作业对资源的需求,以及按照一定的调度算法,从外存的后备队列中选取某些作业调入内存,并为它们创建进程、分配必要的资源。最后将新创建的进程排在就绪队列上等待调度
2.2先来先服务调度算法FCFS
FCFS既可用于作业调度,也可用于进程调度
当作业调度中采用FCFS算法时,系统按照作业到达的先后次序来进行调度,或者说它优先考虑在系统中等待时间最长的作业,而不管该作业所需执行时间的长短
当进程调度中采用FCFS算法时,每次调度是从就绪的进程队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行
2.3短作业优先调度算法SJF
以作业的长短来计算优先级,作业越短,其优先级越高(作业的长短以作业所要求的运行时间来衡量)
缺点:
- 必须预知作业的运行时间
- 对长作业不利
- 人——机无法实现交互
- 完全未考虑作业的紧迫程度,不能保证紧迫性作业能得到及时处理
2.4高响应比优先调度算法HRRN
既考虑作业的等待时间,又考虑作业的运行时间
引入一个动态优先级:优先权=(等待时间+要求服务时间)/要求服务时间
等待时间与服务时间之和是系统对该作业的响应时间,故优先级相当于相应比Rp:Rp=(等待时间+要求服务时间)/要求服务时间=响应时间/要求服务时间
- 若作业等待时间相同,要求服务的时间越短,优先权越高,类似SJF算法,利于短作业
- 若服务时间相同,优先权取决于等待时间,类似FDFS算法,利于长作业
- 对于长作业的优先级,随着等待时间的增加而提高,当其等待时间足够长也可获得处理器
三、进程调度
对系统性能影响最大的一种处理器调度
3.1进程调度的任务、机制、方式
1、任务
- 保存处理器的现场信息
- 按某种算法选取进程
- 把处理器分配给进程
2、调度机制
- 排队器:将系统中的所有就绪进程按一定策略排成一个或多个队列。每当有一个进程转变为就绪状态时,排队器将它插入到相应的就绪队列
- 分派器:从就绪队列中选出依据调度程序选中的进程,进行从分派器到新选进程间的上下文切换,把处理器分配给新选进程
- 上下文切换器:处理器切换时发生两对上下文切换操作。第一次,OS保存当前进程的上下文,把当前进程的处理器寄存器内容保存到该进程的PCB内的相应单元,再装入分派程序的上下文以便运行;第二次,移出分派程序的上下文,把新选进程的CPU现场信息装入处理器的各个相应寄存器内以便新选进程运行
3、调度方式
非抢占方式:一旦把处理器分配给某进程,就让它一直运行下去,直至该进程完成,或发生某事件而被阻塞时,才把处理器分配给其他进程
抢占方式:允许调度程序根据某种原则暂停某个正在执行的进程,将已分配给该进程的处理器重新分配给另一进程
“抢占”必须遵循一定原则:
- 优先权原则
- 短进程优先原则
- 时间片原则:各进程按时间片轮转运行时,当正在执行进程的一个时间片用完后,停止该进程的执行而重新进行调度
3.2时间片轮转调度算法
让就绪队列的每个进程每次仅运行一个时间片。若就绪队列上有 n个进程,每个进程每次大约获得 1/n的处理时间
1、基本原理
根据先来先服务的原则,将需要执行的所有进程按照到达时间的大小排成一个升序的序列,每次都给一个进程同样大小的时间片。在时间片内如果进程执行结束,把进程从进程队列中删去,否则把该进程停止然后改为等待状态,放到进程队列的尾部,直到所有的进程都已执行完毕
2、进程的切换
时间片够用:在该时间片内,进程可以运行至结束,进程运行结束之后,将进程从进程队列中删除,然后启动新的时间片
时间片不够用:在该时间片内,进程只能完成它的一部分任务,在时间片用完之后,将进程的状态改为等待状态,将进程放到进程队列的尾部,等待cpu的调用
3、关于时间片大小的选择
时间片过小,则进程频繁切换,会造成cpu资源的浪费
时间片过大,则轮转调度算法就退化成了先来先服务算法
3.3优先级调度算法
1、优先级调度算法的类型
- 非抢占式优先权调度算法
系统一旦把处理机分配给优先权最高的进程后,便一直执行下去,至完成。 - 抢占式优先权调度算法
只要系统中出现一个新的就绪进程,就进行优先权比较。若出现优先权更高的进程,则立即停止当前执行,并将处理机分配给新到的优先权最高的进程
2、优先级类型
- 静态优先级
静态优先权在创建进程时确定,且在进程的整个运行期间保持不变
确定优先级大小的依据:
- 进程类型(系统进程的优先级高于一般用户进程)
- 进程对资源的需求(资源越少优先级越高)
- 用户要求(紧迫程度和用户所付费用多少)
- 动态优先级
创建进程之初先赋予其一个优先级,其值随进程的推进或等待时间的增加而改变
3.4多级反馈队列调度算法
调度机制:
- 设置多个就绪队列。每个队列赋予不同优先级,第一队列最高,往后递减;不同队列进程赋予的执行时间片大小不同,优先级越高的队列,时间片越小
- 每个队列采用FCFS算法。新进程进入内存后,首先放入第一队列末尾按FCFS原则调度;若在一个时间片内完成则撤离系统,否则转入第二队列末尾等待调度;以此类推,进程被降到第 n队列后按RR方式运行
- 按队列优先级调度。首先调度最高优先级队列中的进程运行,仅当第1~(i-1)所有队列均空时才调度第 i队列中的进程运行;若处理器在第 i队列中为某进程服务时,有新进程进入任一优先级较高队列,立即把正在运行的进程放置该队列队尾,把处理器分配给新到的高优先级进程
四、死锁
4.1死锁的概念
4.1.1资源问题
引起死锁的主要是需要采用互斥访问方法的、不可以被抢占的资源,即临界资源
1、可重用性资源和可消耗性资源
- 可重用性资源:可被多个进程多次使用,如所有硬件
- 可消耗性资源:又称临时性资源,是在进程运行期间,由进程动态的创建和消耗的
可消耗性资源通常是由生产者进程创建,由消费者进程消耗。最典型的可消耗资源是用于进程间通信的消息
2、可抢占性资源和不可抢占性资源
- 可抢占资源:某进程在获得这类资源后,该资源可以再被其他进程或系统抢占。这类资源不会引起死锁,CPU 和内存均属于可抢占性资源
- 不可抢占资源:一旦系统把某资源分配给该进程后,就不能将它强行收回,只能在进程用完后自行释放。打印机等属于不可抢占性资源
死锁的起因通常源于多个进程对资源的争夺,不仅对不可抢占性资源进行争夺时会引起死锁,对可消耗性资源进行争夺时也会引起死锁
4.1.2死锁的定义、必要条件和处理方法
1、定义
如果一组进程中的每一个进程都在等待仅有该组进程中的其他进程才能引发的事件,那么该组进程是死锁的
2、产生死锁的必要条件
- 互斥条件:在一段时间内,某资源只能被一个进程占用
- 请求和保持条件:进程已保持至少一个资源但又提出新的资源请求,而该资源被其他进程占用,请求进程被阻塞但对已获得的资源保持不放
- 不可抢占条件:进程已获得的资源只能在使用完时由自己释放
- 循环等待条件:发生死锁时必然存在一个进程——资源的循环链
3、处理方法
- 死锁预防
- 死锁避免
- 死锁检测
- 死锁解除
4.2死锁预防
4.2.1破坏“请求和保持”条件
必须做到:当一个进程请求资源时,它不能持有不可抢占资源。可通过两种不同的协议实现
第一种协议
所有进程在开始运行之前,必须一次性的申请其在整个运行过程中所需的全部资源。若系统有足够的资源分配,就把所有资源分配给它,这样进程在运行期间就不会提出资源要求(破坏“请求”条件)
分配资源时,只要有一种资源不能满足进程的要求,即使其他所需的各种资源都空闲也不分配给该进程,而让该进程等待(破坏“保持”条件)
第二种协议
允许一个进程只获得运行初期所需的资源后便开始运行,进程运行过程中在逐步释放已分配给自己的、且已用毕的全部资源,然后再请求新的所需资源
4.2.2破坏“不可抢占”条件
当一个已经保持了某些不可抢占资源的进程,提出新的资源请求而不能得到满足时,必须释放已保持的所有资源,待以后需要时再重新申请
4.2.3破坏“循环等待”条件
对系统所有资源类型进行线性排序,赋予不同的序号。每个进程必须按序号递增的顺序请求资源
如果某进程已请求到一些序号较高的资源,又想请求一个序号低的资源,必须释放所具有相同和更高序号的资源后才能申请序号低的资源
规定:每种资源的序号应根据大多数进程需要资源的先后顺序来确定
4.3死锁避免
4.3.1系统安全状态
死锁避免方法中,把系统分为安全状态和不安全状态
处于安全状态时可避免死锁,反之可能进入死锁
1、安全状态
系统能按某种进程推进顺序(P1,P2,...,Pn)为每个进程Pi分配所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利完成。此时称(P1,P2,...,Pn)为安全序列,系统处于安全状态;如果系统找不到这样一个序列,则处于不安全状态
2、安全状态举例
4.3.2银行家算法
每一个新进程在进入系统时,必须申明在运行过程中可能需要每种资源类型的最大单元数目,其数目不应超过系统所拥有的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程。若有,再进一步计算将这些资源分配给进程后,是否会使系统处于不安全状态;如果不会,才将资源分配给它,否则让进程等待
1、银行家算法的数据结构
- 可利用资源向量Avaliable。这是一个含有m个元素的数组,其中每一个元素代表一类可利用的资源数目,其初始值是系统所配置的该类全部可用资源的数目,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态的改变。如果Available[j]=K,则表示系统中现有Rj类资源的最大数目为K
- 最大需求矩阵Max。是一个n×m的矩阵,定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i, j]=K,则表示进程i需要Rj类资源的最大数目为
- 分配矩阵Allocation。是一个n×m的矩阵,定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i, j]=K,则表示进程i当前已分得Rj类资源的数目为K
- 需求矩阵Need。是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i, j]=K,则表示进程i还需要Rj类资源K个方能完成其任务。
矩阵间的关系:Need[i, j]=Max[i, j]-Allocation[i, j]
2、银行家算法
Request的下角标 i 用[i]代替
设Requet[i]是进程Pi的请求向量,如果Requet[i][j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按以下步骤进行检查
- 列表项如果Requet[i][j]<=Need[i, i] (0<=j<=m)便转向(2),否则认为出错(出错是因为所需要的资源已经超过它所宣布的最大值)
- 如果Request[i][j]<=Available[j] (0<=j<=m),便转向(3),否则表示尚无足够资源,Pi必须等待
- 系统试探着把资源分配给进程Pi,并修改相应的数据(并非真的分配,修改数值只是为了做预判):
Available = Available - Request[i]
Allocation[i, j] = Allocation[i, j] + Request[i][j]
Need[i, j]= Need[i, j]- Request[i][j] - 操作系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi;否则将本次试探分配作废,恢复原来的资源分配状态,让进程Pi等待
3、安全性算法
- 设置两个向量
- 工作向量Work,表示系统可提供给进程继续运行所需的各类资源数目,含有m个元素,在执行安全算法开始时,Work=Available
- Finish,表示系统是否有足够的资源分配给进程,使之运行完成。先令Finish[i]=false;当有足够资源分配给进程时,令Finish[i]=true。
- 从进程集合中找到一个能满足下述条件的进程
- Finish[i]=false
- Need[i, j] ≤ Work[j]
若找到,执行步骤(3),否则,执行步骤(4)。
- 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故执行:
Work[j]=Work[j]+Allocation[i, j]
Finish[i]=true
返回步骤(2) - 如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态,否则系统处于不安全状态
4.4死锁检测与解除
4.4.1死锁检测
1、资源分配图
由一组结点N和一组边E组成的对偶G=(N,E)
定义与限制:
- 把 N分成互斥的子集,一组进程结点P={P1,P2,...,Pn}和一组资源结点R={R1,R2,...,Rn}
- 凡属于 E的边 e都连接着 P和 R中的一个结点。e={Pi,Rj}是资源请求边,由进程 Pi指向资源 Rj,表示 Pi请求一个单位的 Rj;E={Rj,Pi}是资源分配边,由资源 Rj指向进程 Pi,表示把一个单位的 Rj分配给 Pi
圆圈代表一个进程,方框代表一类资源。由于一种类型的资源可能有多个,用方框中的一个点代表一类资源中的一个资源
如图,P={P1,P2},R={R1,R2};E={(P1,R2),(R2,P2),(P2,R1),(R1,P1)}
即 P1进程已分得2个 R1资源,又请求1个 R2资源;P2进程已分得1个 R1和 1个 R2资源,又请求1个 R1资源
2、死锁定理
简化资源分配图以判断系统是否死锁。简化方法:
- 在资源分配图中,找出既不阻塞又不是孤点的进程 Pi。顺利的话,Pi获得资源直至运行完毕,然后释放占有资源,相当于消去 Pi的请求边和分配边,使之成为孤立节点。图 a中 P1消去2个分配边,1个请求边变成图 b
- P1释放资源后,P2获得资源继续运行,直至运行完毕释放占有资源。图 b中 P2消去1个分配边,2个请求边变成图 c
- 经过一系列简化,若能消去图中所有边,是所有进程结点变为孤立结点,则称该图是可完全简化的,否则是不可完全简化的
S为死锁状态的充分条件是:当且仅当S状态的资源分配图是不可完全简化的。该条件称为死锁定理
4.4.2死锁解除
方法:抢占资源分配死锁进程,终止(或撤销)死锁进程
1、终止进程的方法
- 终止所有死锁进程
- 逐个终止进程
每终止一个进程都需要用死锁检测算法确定系统死锁是否解除若未解除还需终止另一个进程。代价可能很大
2、付出代价最小的死锁解除算法
从死锁状态 S中先终止一个死锁进程 P1,使系统状态由S变成U1,将P1记入被终止进程的集合d(T),把付出的代价C1加入Rc(T)中;对死锁进程P2、P3等重复上述过程,得到状态U1,U2,...Ui,Un后,再按终止进程时花费代价的大小,把它插入由S状态演变的新状态的队列L中。显然队列L中的第一个状态U1是由S状态花费最小代价演变成的状态
终止一个进程后,若系统仍处于死锁状态,再从U1状态按上述处理方式依次终止一个进程,得到U1',U2',...,Uk'状态,再从U'状态中选取一个代价最小的Uj',如此下去直到死锁解除
花费代价:R(S)min=min{Cui}+min{Cuj}+min{Cuk}+...