Linux - 进程调度算法浅析

Linux - 进程调度算法浅析

一、基础知识

周转时间 = 作业完成时刻 - 作业到达时刻;
带权周转时间 = 周转时间 / 服务时间;
平均周转时间 = 作业周转总时间 / 作业个数;
平均带权周转时间 = 带权周转总时间 / 作业个数;
等待时间 = 作业开始执行时刻 - 作业到达时刻
平均等待时间 = 等待总时间 / 作业个数

二、调度算法FCFS

1.先来先服务算法

  • 策略:按照作业进入系统的先后次序来挑选作业,先进入系统的作业优先被挑选。 这是一种非剥夺式(非抢占式)算法。
  • 效果:算法容易实现,效率不高,只顾及作业等候时间,没考虑作业要求服务时间的长短,不利于短作业而优待了长作业,有利于CPU繁忙型作业而不利于I/O繁忙型作业。

例如,三个作业同时到达系统并立即进入调度:

作业名 所需CPU时间
作业1 28
作业2 9
作业3 3

采用FCFS算法,三个作业的周转时间分别为:28、37和40,因此,平均作业周转时间T = (28+37+40)/3 = 35
若三个作业提交顺序改为作业2、1、3,平均作业周转时间约为29。
若三个作业提交顺序改为作业3、2、1,平均作业周转时间约为18。
FCFS调度算法的平均作业周转时间与作业提交的顺序有关。

2.最短作业优先算法SJF(Shortest Job First)

  • 策略:最短作业优先算法以进入系统的作业所要求的CPU时间为标准,总选取估计计算时间最短的作业投入运行。这是一种非剥夺式调度算法。
  • 性能:算法易于实现,效率不高(相对于剥夺式算法),弱点是需要预先知道作业所需的CPU时间,而这个时间只能靠估计,估计值很难精确,若估计过低,系统可能提前终止该作业;忽视了作业等待时间,会出现饥饿现象;由于缺少剥夺机制,对分时、实时处理很不理想。

例如,四个作业同时到达系统并立即进入调度:

作业名 所需CPU时间
作业1 9
作业2 4
作业3 10
作业4 8

假设系统中没有其他作业,现实施SJF调度算法,
SJF的作业调度顺序为作业2、4、1、3,
平均作业周转时间 T = (4+12+21+31)/4 = 17
平均带权作业周转时间W=(4/4+12/8+21/9+31/10)/4 = 1.98
如果对它们施行FCFS调度算法
平均作业周转时间 T = (9+13+23+31)/4 = 19
平均带权作业周转时间 W = (9/9+13/4+23/10+31/8)/4 = 2.51
SJF的平均作业周转时间比FCFS要小,故它的调度性能比FCFS好。
缺陷:实现SJF调度算法需要知道作业所需运行时间,否则调度就没有依据,要精确知道一个作业的运行时间是办不到的

3.最短剩余时间优先SRTF算法

  • 把SJF算法改为抢占式的调度算法:当一个作业正在执行时,一个新作业进入就绪状态,如果新作业需要的CPU时间比当前正在执行的作业剩余下来还需的CPU时间短,SRTF**强行赶走**当前正在执行的作业。

例如,四个作业非同时到达系统并立即进入调度:

作业名 到达系统时间 所需CPU时间
作业A 0 8
作业B 1 4
作业C 2 5
作业D 3 9

执行顺序分析:
ABBBBCCCCCAAAAAAADDDDDDDDD
A的等待时间:10-1=9(-1是将前面的A减去)
B的等待时间:1-1=0(-1是减去系统到达时间)
C的等待时间:5-2=3
D的等待时间:17-3=14
平均等待时间:(9+3+14)/4 = 6.5
采用非抢占式SJF调度,平均等待时间是:
((8-1)+(12-2)+(17-3))/4=7.75

响应比最高者优先(HRRF)算法

  • 先来先服务算法FCFS与最短作业优先SJF算都法是片面的调度算法。FCFS只考虑作业等候时间而忽视了作业的计算时问,SJF只考虑用户估计的作业计算时间而忽视了作业等待时间。
  • 响应比最高者优先(HRRF)算法是介乎这两者之间的折衷算法,既考虑作业等待时间,又考虑作业的运行时间,既照顾短作业又不使长作业的等待时间过长,改进了调度性能。 缺点是每次计算各道作业的响应比会有一定的时间开销,需要估计期待的服务时间,性能比SJF略差。
  • 响应比定义:作业进入系统后的等待时间与估计计算时间之和称作该作业的响应时间,作业的响应时间除以作业估计计算时间称作响应比,即:
  • 响应比 =1+已等待时间/估计运行时间
    每当调度一个作业运行时,都要计算后备作业队列中每个作业的响应比,选择响应比最高者投入运行。
  • 响应比最高者优先(HRRF)算法的效果:
    • 短作业容易得到较高响应比
    • 长作业等待时间足够长后,也将获得足够高的响应比
    • 饥饿现象不会发生
      响应比最高者优先(HRRF)算法的调度时间:每一个新作业到来时,响应比最高优先算法也可以改造成剥夺式的,把响应比改为响应比 =1+已等待时间/估计剩余运行时间

例如,四个作业非同时到达系统并立即进入调度:

作业名 到达系统时间 所需CPU时间
作业1 0 20
作业2 5 15
作业3 10 5
作业4 15 10

对作业流执行HRRF调度算法
开始只有作业1,被选中执行时间20;
作业1执行完毕,响应比依次为1+15/15、1+10/5、1+5/10,作业3被选中,执行时间5;
作业3执行完毕,响应比依次为1+20/15、1+10/10,作业2被选中,执行时间15;
作业2执行完毕,作业4被选中,执行时间10;
平均作业周转时间T = (20+25-10+40-5+50-15)/4 = 33.75
平均带权作业周转时间
W = (20/20+15/5+35/15+35/10)/4 = 2.375

优先级调度算法

  • 这种算法是根据确定的优先级来选取进程/线程,每次总是选择优先级最高的作业。
  • 可以采取剥夺与非剥夺两种形式
    • 剥夺式:后到来的优先级高的进程强迫正在运行的低优先级进程暂停;
    • 非剥夺式:同时到来的进程中选择高优先级的进程先运行,但是后到来的高优先级进程只能等当前正在运行的低优先级进程结束或者主动出让处理器。
  • 规定用户进程优先级的方法
    • 一种是由用户自己提出进程的优先级。
    • 另一种是由系统综合考虑有关因素来确定用户进程的优先级。
  • 进程/线程优先级的确定有两种方式:
    • 静态:在创建进程/线程时即确定,在整个生命周期里不改变;动态:进程/线程的优先级随时间而改变;
    • 另一种是由系统综合考虑有关因素来确定用户进程的优先级。

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

  • 每次把CPU分配给就绪队列首进程(线程)使用规定的时间间隔(时间片),就绪队列中的每一个进程(线程)轮流运行一个时间片,当时间片耗尽,就强迫当前进程(线程)让出CPU,转到就绪队列队尾,等待下一轮调度。
  • 需要使用间隔时钟。
  • 轮转调度是一种剥夺式调度,系统耗费在进程(线程)切换上的开销比较大,这个开销与时间片的大小有关。
  • 时间片的选取:
    • 时间片太小,导致进程频繁切换,开销显著增大,因此,从系统效率看,时间片应该大一些;
    • 时间片太大,随着进程数目增加,每个进程轮转一次所耗费的时间加长,导致每个进程(线程)的相应速度放慢,因此,从响应时间看,时间片应该小一些。
  • 为了满足用户对响应事件的要求,要么限制就绪队列中进程(线程)数量要么采用动态的时间片长度,根据当前负载状况,及时调整时间片大小
  • 综合起来,确定时间片的长度要从进程数目、切换开销、系统效率和响应时间等多个方面加以考虑。

7.多级反馈队列调度Multi-Level Feedback Queue

  • 设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二队次之,其余队列优先级依次降低。仅当第1~i-1个队列均为空时,操作系统调度器才会调度第i个队列中的进程。赋予各个队列中进程执行时间片的大小也各不相同。在优先级越高的队列中,每个进程的执行时间片就越小。
  • 当一个新进程需要加入就绪队列时,操作系统首先将它放入第一队列的末尾,按FCFS的原则排队等待调度。若轮到该进程执行且在一个时间片结束时尚未完成,则操作系统调度器便将该进程转入第二队列的末尾,再同样按先来先服务原则等待调度执行。如此下去,当一个长进程从第一队列降到最后一个队列后,在最后一个队列中,可使用FCFS或RR调度算法来运行处于此队列中的进程。
  • 如果处理机正在第i(i > 1)队列中为某进程服务时,又有新进程进入第k(k < i)的队列,则新进程将抢占正在运行进程的处理机,即由调度程序把正在执行进程放回第i队列末尾,重新将处理机分配给处于第k队列的新进程。
  • MLFQ调度算法会导致饥饿问题:例如一个长作业进入系统,它最终必将进入优先级最低的就绪队列,如果不断有新的短作业进入系统,且形成稳定的作业流,则长作业只能永远等待。解决的办法是:对于在低优先级队列中等待时间足够长的进程提高优先级,从而让它获得运行机会。

你可能感兴趣的:(Linux,进程间调度)