一些小概念
1. 作业&进程
- 作业:用户的计算任务称为作业
- 进程:程序的执行过程
- 一个作业通常经过两级调度才能在CPU上执行,首先是作业调度,它把选中的一批作业放入内存,并分配其他必要资源,为这些作业建立相应的进程,然后进程调度加粗样式按照一定的算法从就绪进程中选出一个合适进程,使之在CPU上运行
2. 周期
- 周期时间: 假设一个任务的周期时间为20ms,处理时间为10ms,即每当任务执行10ms后,下次执行至少是20ms后
一. 处理机调度的层次和调度算法的目标
1.1 处理机调度的层次
- 高度调度:又称长程调度或作业调度,调度对象是作业,主要功能是根据某种算法,决定将外存上处于后备队列中的哪几个作业调入内存,为他们创建进程、分配必要的资源,并将它们放入就绪队列,高级调度主要用于多批道处理系统中,而在分时和实时系统中不设置高级调度
- 低级调度:又称短程调度或进程调度,调度对象是进程(或内核级线程)。主要功能是,根据某种算法,决定将就绪队列中的哪个进程应获得处理机,并由分派程序将处理及分配给选中的进程。进程调度是最基本的一种调度,多批到处理、分时和实时三种OS中都必须配置这级调度
- 中级调度:又称内存调度,主要目的是提高内存利用率和系统吞吐量,为此,应把那些暂时不能运行的进程,调至外存等待,此时的进程状态成为就绪驻外存状态(挂起状态)。当它们已具备运行条件且外存有空闲时,由中级调度来决定,把外村上的那些具备运行条件的就绪程序再重新调入内存,并修改其为就绪状态,并挂在就绪队列上等待。中级调度实际上就是存储器管理中的对换功能
- 进程调度的运行频率最高,为避免调度本身占用太多CPU,不宜使用进程调度算法太复杂
- 作业调度周期较长,往往发生在一批作业已经完成并退出系统,又需要调入一批作业进入内存时,由于频率较低,允许作业调度算花费较多时间
- 中级调度运行频率基于两者之间
1.2 处理机调度算法的目标
- 处理机调度算法的共同目标
- 资源利用率
- 公平性:使进程都获得合理的CPU时间,不会发生进程饥饿现象。公平是相对的,对相同类型的进程应获得相同的服务,对不同类型的进程,由于其紧急程度或重要性不同,应提供不同的服务
- 平衡性:有的进程属于计算行作业,有的属于IO型,为了使系统中的CPU和各种外部设备都能经常处于忙碌状态,调度算法应尽可能保持资源使用的平衡性
- 策略强制执行:对所制订的策略其中包括安全策略,只要需要,就必须予以准确的执行,即使会造成某些工作的延迟
- 批处理系统的目标
- 平均周转时间短:指从作业被提交给系统开始,到作业完成为止的这段时间间隔。它包括四部分时间:作业在外存后备队列上等待(作业)调度的时间,进程在就绪队列上等待进程调度的时间,进程在CPU上执行的时间,继承等待I/O操作完成的时间,其中后三项在一个作业的整个处理过程中,可能发生多次
- 系统吞吐量高:由于吞吐量是指在单位时间内系统完成的作业数,因而它与批处理作业的平均长度有关
- 处理机利用率高:调度方式和算法对处理机的利用率起着十分重要的作用,如果单纯为使处理及利用率高,需要选择计算量大的作业运行,由上,这些要求存在着一定的矛盾
- 分时系统的目标
- 响应时间快:指用户通过键盘提交一个请求开始,直到屏幕上显示出处理结果为止的一段时间间隔,包括将信息传到处理机处,处理机处理、将响应信息会送到终端三部分时间
- 均衡性: 系统响应时间的快慢与用户所请求服务的复杂性相适应
- 实时系统的目标
- 截止时间的保证: 指某任务必须开始执行的最迟时间,或必须完成的最迟时间
- 可预测时间: 在实时系统中,可预测性非常重要,如多媒体系统中,无论是电影还是电视剧都应是连续播放,这就提供了请求的可预测性
二. 作业与作业调度
在多批到处理处理系统中,作业时童虎提交给系统的一项相对独立的工作。操作员把用户提交的作业通过相应的输入设备输入到磁盘存储器,并保证在一个后备作业队列中,再由作业调度程序将其从外存调入内存
2.1 批处理系统中的作业
2.1.1 作业和作业步
- 作业是一个比程序更为广泛的概念,不仅包含了通常的程序和数据,还配有一份作业说明书,系统根据该说明书来对程序的运行进行控制,批处理系统中,作业时外存调入内存的基本单位
- 作业步,在作业运行期间,每个作业都必须经过若干个相对独立,有相互关联的顺序加工步骤才能得到结果,即作业步。一个典型的作业可分为:编译作业步,链接装配作业步和运行作业步
2.1.2 作业控制块(JCB)
- 保存了系统对作业进行管理和调度所需的全部信息
- 通常JCB中有:作业标识、用户名称、用户账号、作业类型(CPU繁忙,IO繁忙,批量,终端)、作业状态、调度信息(优先级,作业运行时间)、资源需求(预计运行时间,要求内存大小)、资源使用情况
- 当一个作业进入系统时,便由作业注册程序为该作业建立一个JCB,再根据类型放到相应的作业后备队列等待调度
- 系统按照JCB中的信息和作业说明书对作业进行控制
2.1.3 作业运行的三个阶段和三种状态
- 收容阶段(后备状态) :操作员吧用户提交的作业通过某种输入方式或SPOOLing系统输入到硬盘上,再为该作业建立JCB,并把它放入后备队列中
- 运行阶段(运行状态):作业被作业调度选中后,便为它分配必要的资源和建立线程,并放入就绪队列。作业从第一次进入就绪状态开始到结束前,都处于运行状态
- 完成阶段(完成状态):作业运行完成,或发生异常情况而提前结束时,作业进入完成阶段。系统回收资源,并将作业运行结果信息形成输出文件后输出
2.2 作业调度的主要任务
作业调度的主要任务是:根据JCB中的信息,检查系统中的资源能否满足作业对资源的需求,以及按照一定的调度算法,从外存的后备队列中选某些作业调入内存,并为它们创建进程、分配必要的资源。然后再将新创建的进程排在就绪队列上等待调度,每次执行作业调度时,都需要做出以下两个决定
2.2.1 接纳多少个作业
- 每一次作业调度时,从后备队列中取多少作业调入内存,取决于多道程序度,即允许多少个作业同时在内存中运行
- 作业多有利于提高CPU的利用率及系统吞吐量,但是内存会不足,导致中断
- 多道程序度的确定时根据计算机的系统规模,运行速度,作业大小以及能否获得较好的系统性能等情况作出适当的抉择的
2.2.2 接纳哪些作业
- 应选择后备队列中的哪些作业调入内存,取决于所采用的调度算法
- 批处理系统中,作业进入系统后,总是先驻留在外存的作业后备队列上,因此需要作业调度,,以便将它们分批装入内存
- 分时系统,实时系统中,为了做到及时响应,用户通过键盘输入的命令或数据等都直接送入内存,因此不需要作业调度机制,但需要某种接纳控制措施来限制进入系统的用户数目
2.3 先来先服务(FCFS)
- 最简单的调度算法,可用于作业调度,也可用于进程调度
- 已较少使用,但是经常与其他调度算法结合使用,形成一种更有效的调度算法。如:可以在系统中按进程的优先级设置多个队列,每个同优先级队列的调度都基于FCFS
2.4 短作业优先(SJF)调度算法
- 以作业长短来计算作业优先级
- 短作业优先算法缺点:
- 必须预知作业的运行时间
- 对长作业非常不利
- 未考虑作业的紧迫程度
2.5 优先级(PSA)调度算法
基于作业的紧迫程度,由外界赋予作业相应的优先级
2.6 高响应比优先调度算法
- 等待时间相同,则短作业优先
- 要求服务时间相同(作业所需时间),则等待时间长的优先
- 长作业的优先级会随时间的增加而提高
三. 进程调度
3.1 进程调度的任务、机制和方式
3.1.1 任务
- 保存处理机的现场信息:在进行调度时首先需要保存当前进程的处理机的现场信息,如程序计数器,多个通用寄存器中的内容
- 按某种算法选取进程
- 把处理器分配给进程:由分派程序把处理器分配给该进程,此时需要将选中进程的进程控制块内有关处理机现场的信息装入处理器相应的各个寄存器中,把处理器的控制权交予该进程,让它从上次的断点处恢复运行
3.1.2 进程调度机制
- 排队器:为了提高进程调度的效率,应事先将系统中的所有就绪进程按照一定的策略排成一个或多个队列,以便调度程序能最快的找到它,以后每当有一个进程转变为就绪状态时,排队器便将它插入到相应的就绪队列
- 分配器:分派器依据进程调度程序所选定的进程,将其从就绪队列中取出,然后进行从分派器到新选出进程间的上下文切换,将处理器分配给新选出的进程
- 上下文切换器:对处理机进行切换时,会发生两对上下文的切换操作:
-
第一对上下文切换时,OS将保存当前进程的上下文,即把当前进程的处理机寄存器内容保存到进程的进程控制块内相应单元,再装入分派程序的上下文,以便分派程序运行
-
第二对上下文切换是移出分派程序的上下文,而把新选进程的CPU现场信息装入到处理机的各个相应寄存器中,以便新选进程运行
-
在进行上下文切换时,需要执行大量的load和store等指令操作,以保存寄存器的内容,每一次切换所花费的时间大约可以执行上千条指令,为此,现在已有靠硬件实现的方法来减少上下文切换时间,一般采用两组(或多组)寄存器,其中的一组寄存器供处理机再系统态时使用,另一组寄存器供应用程序使用,在这种条件下的上下文切换,只需要改变指针,使其指向当前寄存器即可
3.1.3 进程调度方式
1. 非抢占式
采用该方式时,一旦处理机分配给某进程后,就让它一直运行下去,绝不会因为时钟中断或者其他任何原因去抢占当前正在运行进程的处理机,直至该进程完成或阻塞时,才会把处理机分配给其他进程,这种方式优点是实现简单,系统开销小,适用于大多数的批处理系统,但不能用于分时系统和大多数实时系统采用该方式可将引起进程调度的因素归结为:
- 正在执行的进程运行完毕,或因发生某事件而使其无法再继续运行
- 正在执行中的进程因提出I/O请求而暂停执行
- 在进程通信或者同步过程中,执行路某种原语,如Bolck
2. 抢占方式
这种方式允许调度程序根据某种原则去暂停某个正在执行的进程,将已分配给该进程的处理机重新分配给另一进程,现代OS广泛采用抢占式。分时系统中,只有采用抢占式才有可能实现人-机交互。实时系统中,抢占式也能满足实时任务的需求。但抢占式比较复杂,所付出的系统开销也较大。抢占式必须遵循以下原则:
- 优先权原则:指允许优先级高的新到进程抢占当前进程的处理机
- 短进程优先原则:只允许新到的短进程抢占当前长进程的处理机
- 时间片原则:各进程按时间片轮转运行时,当正在执行的进程的一个时间片用完后,便停止该进程的执行而重新调度
3.2 轮转调度算法
分时系统中,最简单也较常用的时基于时间片的轮转(RR)调度算法。该算法让就绪队列上的每个进程每次仅运行一个时间片。
3.2.1 轮转法基本原理
- 在轮转(RR)法中,系统将所有的就绪进程按FCFS策略排成一个就绪队列
- 系统设置每隔一定时间( 如 30ms)便产生一次中断,去激活进程调度程序进行调度,把CPU分配给队首进程,令其执行一个时间片
3.2.2 进程切换时机
- 若一个时间片尚未用完,正在运行的进程便已完成,就立即激活调度程序,将它从队列中删除,再调度就绪队列中队首的进程运行,并启动一个新的时间片
- 在一个时间片用完时,计时器中断处理程序被激活,如果进城尚未运行完毕,调度程序将把它送往就绪队列的末尾
3.2.3 时间片大小的确定
- 小的时间片有利于短作业,但意味着会频繁地执行进程调度和进程上下文的切换,增加系统开销
- 大的时间片 RR算法就退化为FCFS算法,无法满足短作业和交互式用户的需求
- 较为可取的时间片大小是略大于一次典型的交互所需要的时间
3.3 优先级调度算法
时间片轮转(RR)算法是默认系统中所有的进程紧迫性是相同的,但实际并非如此,还需要引入优先级概念
3.3.1 优先级调度算法的类型
优先级进程调度算法,是把处理机分配给就绪队列中优先级最高的进程。这时,又可进一步把该算法分成如下两种类型
- **非抢占式优先级调度算法:**一旦把处理机分配给就绪队列中优先级最高的进程后,该进程便一直执行下去,除非自己阻塞或中断而放弃处理机
- **抢占式优先级调度算法:**在进程执行期间,只要出现了另一个比其优先级更高的进程,调度程序就将处理机分配给新到的优先级最高的进程。抢占式的优先级调度算法常用于对实时性要求较高的系统中
3.3.2 优先级的类型
优先级调度算法关键在于:如何确定进程的优先级,以及确定是使用静态优先级还是动态优先级
- 静态优先级:创建进程时确定的,在进程的整个运行期间保持不变,优先级是利用某一范围内的一个整数表示的,又称为优先数,静态优先级法简单易行,系统开销小但不够精确,可能会出现优先级低的进程长期没有被调度的情况,确定进程优先级大小的依据有如下三个:
- 进程类型:通常系统进程(如接收进程、对换进程)的优先级高于一般用户进程的优先级
- 进程对资源的需求:对资源要求少的进程应赋予较高的优先级
- 用户要求:根据进程的紧迫程度及用户所付费用的多少确定优先级
- 动态优先级:在创建进程之初,先赋予其一个优先级,然后其值随进程的推进或者等待时间的增加而改变,以便获得更好的调度性能
3.4 多队列调度算法
- 前面的各种调度算法,尤其在用于进程调度时,由于系统中仅设置一个进程的就绪队列,即低级调度算法是固定的,单一的,无法满足系统中不同用户对进程调度策略的不同要求,在多机处理中,这种单一调度策略实现机制的缺点更显突出,因此,多级队列调度算法能够在一定程度上弥补这一缺点
- 该算法将系统中的进程就绪队列从一个拆分为若干个,不同类型或性质的进程固定分配在不同的就绪队列,不同的就绪队列采用不同的调度算法,一个就绪队列中的进程可以设置不同的优先级,不同的就绪队列本身也可以设置不同的优先级
- 在多处理机系统这种,由于该算法安排了多个就绪队列,因此很方便的为每个处理机设置一个单独的就绪队列。这样不仅对每个处理机的调度可以实施不同的调度策略,对于一个含有多线程的进程而言,可以根据其要求将所有线程分配在一个就绪队列,全部在一个处理及运行。或者对于一组需要合作的进程或线程而言,也可以分配到一组处理机对应的多个就绪队列,使他们能同时获得处理机并行执行
3.5 多级反馈队列调度算法
- 前面的进程调度算法都有一定的局限性,如果未指明长度,则短进程优先和基于进程长度的抢占式调度算法都无法使用
- 多级反馈队列调度算法则不必事先知道进程所需的执行时间,还可以较好的满足各种类型进程的需要,是目前公认的一种较好的进程调度算法
3.5.1 调度机制
- 设置多个就绪队列:并为每个队列赋予不同的优先级,不同队列中的进程赋予的执行时间片大小也各不相同,优先级愈高的队列时间片就越小,如第二个队列的时间片就要比第一个的时间片长一倍
- 每个队列都采用FCFS算法,当新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则等待调度。轮到该线程执行时,如果它在该时间片内完成,便撤离系统。否则,即在第一个时间片结束时尚未完成,调度程序将其转入第二队列的末尾等待调度(S1 -> S2),依次执行下去,直到队列n(最后一个队列),n队列采用RR方式运行
- 按照队列优先级调度,调度程序首先调度最高优先级队列中的诸程序运行,仅当第一队列空闲时,才调度第二队列中的进程运行,即仅当 1~(i - 1)的队列都空闲时,才会调度第 i 队列,如果正在执行i队列中的某进程时,又有新进程入任优先级较高的队列,此时须立即把正在运行的进程放回第 i 队列的末尾,把处理机分配给新到的高优先级进程
3.5.2 调度算法的性能
在多级反馈队列调度算法中,如果规定第一个队列的时间片略大于多数人机交互所需处理时间时,便能较好的满足各类用户需要
- **终端型用户:**由于终端型用户提交的作业多属于交互性作业,通常较小,系统重要能使这些作业在第一队列规定的时间片内完成,可使终端型用户感到满意
- **短批处理作业用户:**对于这类作业,如果可在第一队列中执行完成,便获得与终端型作业一样的响应时间。对于稍长的短作业,也只需在第二、三队列各自执行一时间片完成,周转时间也较短
- **长批处理作业用户:**对于长作业,它将依次在第1,2,…,n个队列中运行,然后再按轮转方式运行, 用户不必担心长作业长期得不到处理
3.6 基于公平原则的调度算法
以上介绍的几种调度算法所保证的只是优先运行,如优先级算法是优先级最高的作业优先运行,但并保证作业占用了多少处理机时间,也未考虑到调度的公平性
3.6.1 保证调度算法
保证调度算法是另外一种类型的调度算法,它向用户所做出的的保证并不是优先运行,而是明确的性能保证,该算法可以做到调度的公平性。一种比较容易实现的性能保证是处理机分配的公平,即系统中有 n 个相同类型的进程同时运行,则每个进程获得相同的处理机时间 1/n ,实施公平调度算法时系统必须具有以下功能
- 跟踪计算每个进程自创建以来已经执行的处理时间
- 计算每个进程应获得的处理机时间,即自创建以来的时间除以 n
- 计算进程获得处理机时间的比率,即进程实际执行的处理时间和应获得的处理机时间之比
- 比较各进程获得处理机时间的比率,如进程A的比率最低,为0.5,而进程B的比率为0.8,进程C的比率为1.2等
- 调度程序应选择比率最小的进程,将处理机分配给它,并让该进程一直运行,直到超过最接近它的进程比率为止
3.6.2 公平分享调度算法
保证调度算法保证的是进程公平,但是如果一个用户有5个进程(A,B,C,D),另一个用户只有一个进程(E),此时就对用户不公平了,公平分享调度算法是针对用户而言,使是所有用户获得相同的处理机时间,或所要求的时间比例
- 若要两个用户时间相同,则执行以下强制调度序列:A,E,B,E,C,E,D,E,A,E,B,E,C,E,D…
- 若要用户1时间是用户2的两倍:A,B,E,C,D,E,A,B,E,C,D,E
四. 实时调度
在实时系统中,可能存在两类不同性质的实时任务,即
HRT任务
和SRT任务
,它们都联系着一个截止时间。为保证系统正常工作,实时调度必须能满足实时任务对时间的要求
。因此,实时调度的实现应具备一些条件
HRT
(Hard Real-Time):硬实时操作系统必须使任务在确定的时间内完成。(必须确保堆截止时间的要求)SRT
(Soft Real-time):软实时操作系统能让绝大多数任务在确定时间内完成。(基本能保证对截止时间的要求)
4.1 实现实时调度的基本条件
4.1.1 提供必要的信息
- **就绪时间:**某任务成为就绪状态的起始时间
- **开始截止时间和完成截止时间:**对于典型的实时应用,只须知道开始截止时间,或者完成截止时间
- **处理时间:**一个任务从开始执行到完成需要的时间
- **资源要求:**任务执行时所需的一组资源
- 优先级:
- 绝对优先级: 如果该任务的开始截止时间错过,一定会引起故障,则赋予绝对优先
- 相对优先级: 如果该任务的开始截止时间错过,不会对系统造成大影响,则赋予相对优先
4.1.2 系统处理能力强
假定系统中有m个周期性的HRT任务,它们处理时间分别为 Ci ,周期时间为 Pi ,
- 在单机处理下,必须满足下面限制条件系统才会调度:
- 在多机处理下,必须满足下面限制条件系统才会调度:
- 注意:上述的限制条件并未考虑到任务切换所花费的时间
- **提升性能途径一:**采用单处理机系统,但必须增强其处理能力,减少每个任务的处理时间
- **提升性能途径二:**采用多处理机系统
4.1.3 采用抢占式调度机制
设计这种调度机制时,应使所有的实时任务都比较小,并在执行完关键性程序和临界区后能及时将自己阻塞起来,以便释放出处理机,供调度程序去调度那个开始截止时间即将到达的任务
4.1.4 具有快速切换机制
为保证硬实时任务能及时运行,系统中还应具有快速切换机制,使之能进行任务的快速切换,该机制应具有以下两方面能力
- 对中断的快速响应能力:对紧迫的外部事件请求中断能及时响应,要求系统具有快速硬件中断机构,还应该使禁止中断的时间间隔尽量短,以免耽误时机(其他紧迫任务)
- 快速的任务分派能力:为了提高分派程序进行任务切换时的速度,应使系统中的每个运行功能单位适当的小,以减少任务切换的时间开销
4.2 实时调度算法的分类
- 根据实时任务性质,可分为硬实时调度算法和软实时调度算法
- 根据调度方式,可分为非抢占式调度算法和抢占调度算法
4.2.1 非抢占式调度算法
- 非抢占式轮转调度算法,由一台计算机控制若干个相同的或类似的对象,为每一个被控对象建立一个实时任务,并将它们排成一个轮转队列。调度程序每次选择队列中的第一个任务投入运行。任务完成后就把它挂在轮转队列的末尾等待,调度程序在选择下一个队首任务运行,用于要求不太严格的实时系统
- 非抢占式优先调度算法,系统为有一定要求的实时任务赋予了较高的优先级,当这些任务到达时,可以把它们安排在就绪队列的队首,等当前任务自我终止或运行完成后,便可调度执行队首的高优先进程
4.2.2 抢占式调度算法
- 基于时钟中断的抢占式优先级调度算法,在某实时任务到达后,如果它的优先级高于当前任务的优先级,这时不会立即抢占当前任务的处理机,而是等到时钟中断发生时,调度程序才剥夺当前任务的执行,将处理机分配给新到的高优先级任务,该算法能获得较好的响应效果,可用于大多数实时系统中
- 立即抢占的优先级调度算法,这种调度策略中,要求操作系统具有快速响应外部事件中断的能力,一旦出现外部中断,只要当前任务未处于临界区,便能立即剥夺当前任务的执行,把处理机分配给请求中断的急迫任务
4.3 最早截止时间优先EDF算法
- 该算法是根据任务的截止时间确定任务的优先级,任务的截止时间越早,优先级越高
- 该算法既可以用于抢占式调度方式中,也可以用于非抢占式调度方式中
4.3.1 非抢占式调度用于非周期实时任务
每当一个任务执行完后,选出队列中截止时间最近的
4.3.2 抢占式调度用于周期实时任务
会抢占,每个时间片选择下一个截止时间最近的
4.4 最低松弛度优先LLF算法
- 该算法在确定任务的优先级时,根据的是任务的紧急(松弛程度),任务紧急程度越高,赋予该任务的优先级就越高
- 如一个任务在200ms时必须完成,而它本身的运行时间为100ms,因此调度程序必须在100ms之前调度执行,该任务的松弛度为100ms
- 另一个任务在400ms时必须完成,它本身需要150ms,则其松弛程度为250ms
4.4.1 小例子
两个周期性实时任务A和B
- A要求20ms执行一次,执行时间10ms
- B要求50ms执行一次,执行时间25ms
- t1时,A松弛度为10ms,B松弛度为25ms
- t2时,A松弛度为20ms,(必须完成时间40 - 自身需要时间 10 - 当前时间 10),B松弛度为15
4.5 优先级倒置
4.5.1 问题概述
- 假设有三个独立进程,优先级从高到低:P1,P2,P3
- 其中P1跟P3共享一个临界资源
- 此时:P3先到,在进入临界区时候被P2夺走处理机,P3阻塞,此时P1到达,夺走处理机,到达临界区时发现被锁,只能阻塞,直到P2运行完,把处理机还给 P3,P3运行完临界区,才轮到P1
4. 高优先级的P1因P3进程被阻塞,而又因为P2进程存在延长了P1阻塞时间,而且被延长的时间是不可预知和无法限定的,由此产生的优先级倒置现象是非常有害的,它不应该出现在实时系统中
4.5.2 简单的解决方法
进入临界区的线程不能被抢夺处理机,这在临界区都比较短而且不多的情况下是可行的,但如果临界区非常长,会导致更高优先级的线程会等待较长时间
4.5.3 基于动态优先继承方法
当P1进入临界区时,发现有低优先级线程P3先锁住临界区,则此时P1阻塞,且P3暂时继承P1的优先级,直到退出临界区,这样可以有效防止P2插入