在多道程序环境下,主存中有着多个进程,其数目往往多于处理机数目。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之执行。分配处理机的任务是由处理机调度程序完成的。
linux采用抢占式调度算法
处理机调度的层次
在多道程序系统中,一个作业被提交后必须经过处理机调度后,方能获得处理机执行。对于批量型作业而言,通常需要经历作业调度(又称高级调度或长程调度)和进程调度(又称低级调度或短程调度)两个过程后方能获得处理机;对于终端型作业,则通常只需经过进程调度即可获得处理机。在较完善的操作系统中,为提高内存的利用率,往往还设置了中级调度(又称中程调度)。
高级调度
高级调度(High Level Scheduling)又称为作业调度或长程调度(LongTerm Scheduling),其主要功能是根据某种算法,把外存上处于后备队列中的那些作业调入内存。
作业和作业步
(1) 作业(Job)。作业是一个比程序更为广泛的概念,它不仅包含了通常的程序和数据,而且还应配有一份作业说明书,系统根据该说明书来对程序的运行进行控制。在批处理系统中,是以作业为基本单位从外存调入内存的。
(2) 作业步(Job Step)。通常,在作业运行期间,每个作业都必须经过若干个相对独立,又相互关联的顺序加工步骤才能得到结果,我们把其中的每一个加工步骤称为一个作业步,各作业步之间存在着相互联系,往往是把上一个作业步的输出作为下一个作业步的输入。
(3) 作业流。若干个作业进入系统后,被依次存放在外存上,这便形成了输入的作业流;在操作系统的控制下,逐个作业进行处理,于是便形成了处理作业流。
作业控制块 JCB(Job Control Block)
为了管理和调度作业,在多道批处理系统中为每个作业设置了一个作业控制块,如同进程控制块是进程在系统中存在的标志一样,它是作业在系统中存在的标志,其中保存了系统对作业进行管理和调度所需的全部信息。
在 JCB 中所包含的内容因系统而异,每当作业进入系统时,系统便为每个作业建立一个 JCB,根据作业类型将它插入相应的后备队列中。作业调度程序依据一定的调度算法来调度它们,被调度到的作业将会装入内存。在作业运行期间,系统就按照 JCB 中的信息对作业进行控制。当一个作业执行结束进入完成状态时,系统负责回收分配给它的资源,撤消它的作业控制块。
作业调度
作业调度的主要功能是根据作业控制块中的信息,审查系统能否满足用户作业的资源需求,以及按照一定的算法,从外存的后备队列中选取某些作业调入内存,并为它们创建进程、分配必要的资源。然后再将新创建的进程插入就绪队列,准备执行。
在每次执行作业调度时,都须做出以下两个决定。
1) 决定接纳多少个作业
2) 决定接纳哪些作业
低级调度
通常也把低级调度(Low Level Scheduling)称为进程调度或短程调度(ShortTermScheduling),它所调度的对象是进程(或内核级线程)。进程调度是最基本的一种调度,在多道批处理、分时和实时三种类型的 OS 中,都必须配置这级调度。
低级调度的主要功能如下:
(1) 保存处理机的现场信息。
(2) 按某种算法选取进程。
(3) 把处理器分配给进程。
进程调度可采用下述两种调度方式。
1) 非抢占方式(Nonpreemptive Mode)
在采用这种调度方式时,一旦把处理机分配给某进程后,不管它要运行多长时间,都一直让它运行下去,决不会因为时钟中断等原因而抢占正在运行进程的处理机,也不允许其它进程抢占已经分配给它的处理机。直至该进程完成,自愿释放处理机,或发生某事件而被阻塞时,才再把处理机分配给其他进程。
2) 抢占方式(Preemptive Mode)
这种调度方式允许调度程序根据某种原则去暂停某个正在执行的进程,将已分配给该进程的处理机重新分配给另一进程。
调 度 算 法
在 OS 中调度的实质是一种资源分配,因而调度算法是指:根据系统的资源分配策略所规定的资源分配算法。
先来先服务调度算法
先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。
当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存。
FCFS 算法比较有利于长作业(进程),而不利于短作业(进程)。
短作业(进程)优先调度算法
短作业(进程)优先调度算法 SJ(P)F,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。
最高优先权优先(FPF)调度算法
此算法常被用于批处理系统中,作为作业调度算法,也作为多种操作系统中的进程调度算法,还可用于实时系统中。当把该算法用于作业调度时,系统将从后备队列中选择若干个优先权最高的作业装入内存。
高响应比优先调度算法
在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。如果我们能为每个作业引入前面所述的动态优先权,并使作业的优先级随着等待时间的增加而以速率 a 提高,则长作业在等待一定的时间后,必然有机会分配到处理机。
由于等待时间与服务时间之和就是系统对该作业的响应时间,故该优先权又相当于响应比 。据此,又可表示为:
交互式系统中的调度算法
时间片轮转调度算法
优先级反转问题
产生死锁的原因和必要条件
在多道程序系统中,虽可借助于多个进程的并发执行来改善系统的资源利用率,提高系统的吞吐量,但可能发生一种危险——死锁。所谓死锁(Deadlock),是指多个进程在运行过程中因争夺资源而造成的一种僵局(DeadlyEmbrace),当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。在前面介绍把信号量作为同步工具时已提及到,若多个 wait 和 signal 操作顺序不当,会产生进程死锁。
产生死锁的原因
(1) 竞争资源。
(2) 进程间推进顺序非法。
资源分类
可剥夺性资源——是指某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺。例如,优先权高的进程可以剥夺优先权低的进程的处理机。又如,内存区可由存储器管理程序把一个进程从一个存储区移到另一个存储区,此即剥夺了该进程原来占有的存储区。甚至可将一个进程从内存调出到外存上。可见,CPU和主存均属于可剥夺性资源。
不可剥夺性资源——当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。
竞争非剥夺性资源——在系统中所配置的非剥夺性资源,由于它们的数量不能满足诸进程运行的需要,会使进程在运行过程中,因争夺这些资源而陷入僵局。
竞争临时性资源——有一种是所谓的临时性资源,这是指由一个进程产生,被另一进程使用一短暂时间后便无用的资源,故也称之为消耗性资源,它也可能引起死锁。
产生死锁的必要条件
(1) 互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。
(2) 请求和保持条件:指进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
(3) 不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
(4) 环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链
处理死锁的基本方法
(1) 预防死锁。通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或几个条件,来预防发生死锁。
(2) 避免死锁。该方法同样是属于事先预防的策略,但它并不须事先采取各种限制措施去破坏产生死锁的四个必要条件,而是在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁。
(3) 检测死锁。这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,而是允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源; 然后,采取适当措施,从系统中将已发生的死锁清除掉。
(4) 解除死锁。这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤消或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。
预防死锁的方法
预防死锁和避免死锁这两种方法实质上都是通过施加某些限制条件,来预防发生死锁。
两者的主要差别在于:
- 为预防死锁所施加的限制条件较严格,这往往会影响进程的并发执行;
- 为避免死锁所施加的限制条件则较宽松,这给进程的运行提供了较宽松的环境,有利于进程的并发执行。
预防死锁
1、摒弃“请求和保持”条件——所有进程在开始运行之前,都必须一次性地申请其在整个运行过程所需的全部资源。
2、摒弃“不剥夺”条件——当一个已经保持了某些资源的进程,再提出新的资源请求而不能立即得到满足时,必须释放它已经保持了的所有资源,待以后需要时再重新申请。
3、摒弃“环路等待”条件——系统将所有资源按类型进行线性排队,并赋予不同的序号。所有进程对资源的请求必须严格按照资源序号递增的次序提出,这样,在所形成的资源分配图中,不可能再出现环路
利用银行家算法避免死锁
银行家算法中的数据结构
(1) 可利用资源向量 Available。这是一个含有 m 个元素的数组。
(2) 最大需求矩阵 Max。这是一个 n×m 的矩阵,它定义了系统中 n 个进程中的每一个进程对 m 类资源的最大需求。
(3) 分配矩阵 Allocation。这也是一个 n×m 的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。
(4) 需求矩阵 Need。这也是一个 n×m 的矩阵,用以表示每一个进程尚需的各类资源数。
银行家算法
安全性算法
死锁的检测
当系统为进程分配资源时,若未采取任何限制性措施,则系统必须提供检测和解除死锁的手段。为此,系统必须做到:
- (1) 保存有关资源的请求和分配信息;
- (2) 提供一种算法,以利用这些信息来检测系统是否已进入死锁状态。
死锁的解除
当发现有进程死锁时,便应立即把它们从死锁状态中解脱出来。常采用解除死锁的两种方法是:
- (1) 剥夺资源。从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态。
- (2) 撤消进程。最简单的撤消进程的方法是使全部死锁进程都夭折掉;稍微温和一点的方法是按照某种顺序逐个地撤消进程,直至有足够的资源可用,使死锁状态消除为止。
0328补充
基本概念
CPU调度
其任务就是控制、协调进程对CPU的竞争。即按一定的调度算法从就绪队列中选择一个进程,把CPU的使用权交给被选中的进程。
如果没有就绪进程,系统会安排一个系统空闲进程。
CPU调度的时机
当发生上图中事件之后,会引发如下事件的进行:
因此,进程调度的时机有以下四个
进程切换
进程切换工作包括两部分:
- 1、切换全局页目录以加载一个新的地址空间
- 2、切换内核栈和硬件上下文,其中硬件上下文包括了内核执行新进程需要的全部信息,如CPU相关寄存器。
上下文切换的具体步骤:
上下文切换开销
用户的角度和系统的角度对于调度算法的要求
抢占与非抢占
- 可抢占式——CPU永远运行优先级最高的进程,如果有就绪进程的优先级高于当前运行的进程,则剥夺当前运行进程的CPU
- 不可抢占——某一进程被调度运行之后,除非由于他自身的原因不能运行,否则一直运行下去。
IO密集与CPU密集型进程