进程调度详解算法

引言

原因

需要进程调度的理由很简单,即充分利用计算机系统中的CPU资源,让计算机系统能够多快好省地完成我们让它做的各种任务。为此,可在内存中可存放数目远大于计算机系统内CPU个数的进程,让这些进程在操作系统的进程调度器的调度下,能够让进程高效(高的吞吐量—throughput)、及时(低延迟—latency)、公平(fairness)地使用CPU。为此调度器可设计不同的调度算法来选择进程,这体现了进程调度的策略,同时还需并进一步通过进程的上下文切换(context switch)来完成进程切换,这体现了进程调度的机制。总体上说,我们需要何时调度(调度的时机)、是否能够在内核执行的任意位置进行调度(调度的方式)、如果完成进程切换(上下文切换)、如果选择“合适”的进程执行(调度策略/调度算法)、如果评价选择的合理性(进程调度的指标)。了解上述细节,也就可以说是了解了进程调度。

进程调度的指标

不同的进程调度算法具有不同的特征,为此需要建立衡量一个算法的基本指标。一般而言,衡量和比较各种进程调度算法性能的主要因素如下所示:

  • CPU利用率:CPU是计算机系统中的稀缺资源,所以应在有具体任务的情况下尽可能使CPU保持忙,从而使得CPU资源利用率最高。
  • 吞吐量:CPU运行时的工作量大小是以每单位时间所完成的进程数目来描述的,即称为吞吐量。
  • 周转时间:指从进程创建到作进程结束所经过的时间,这期间包括了由于各种因素(比如等待I/O操作完成)导致的进程阻塞,处于就绪态并在就绪队列中排队,在处理机上运行所花时间的总和。
  • 等待时间:即进程在就绪队列中等待所花的时间总和。因此衡量一个调度算法的简单方法就是统计进程在就绪队列上的等待时间。
  • 响应时间:指从事件(比如产生了一次时钟中断事件)产生到进程或系统作出响应所经过的时间。在交互式桌面计算机系统中,用户希望响应时间越快越好,但这常常要以牺牲吞吐量为代价

这些指标其实是相互有冲突的,响应时间短也就意味着在相关事件产生后,操作系统需要迅速进行进程切换,让对应的进程尽快响应产生的事件,从而导致进程调度与切换的开销增大,这会降低系统的吞吐量。

进程调度的时机

进程调度发生的时机(也称为调度点)与进程的状态变化有直接的关系。回顾进程状态变化图,我们可以看到进程调度的时机直接与进程在运行态<—>退出态/就绪态/阻塞态的转变时机相关。简而言之,引起进程调度的时机可归结为以下几类:

  • 正在执行的进程执行完毕,需要选择新的就绪进程执行。
  • 正在执行的进程调用相关系统调用(包括与I/O操作,同步互斥操作等相关的系统调用)导致需等待某事件发生或等待资源可用,从而将白己阻塞起来进入阻塞状态。
  • 正在执行的进程主动调用放弃CPU的系统调用,导致自己的状态为就绪态,且把自己重新放到就绪队列中。
  • 等待事件发生或资源可用的进程等待队列,从而导致进程从阻塞态回到就绪态,并可参与到调度中。
  • 正在执行的进程的时间片已经用完,致自己的状态为就绪态,且把自己重新放到就绪队列中。
  • 在执行完系统调用后准备返回用户进程前的时刻,可调度选择一新用户进程执行
  • 就绪队列中某进程的优先级变得高于当前执行进程的优先级,从而也将引发进程调度。

进程调度的方式

这里需要注意,存在两种进程抢占处理器的调度方式:

  • 可抢占式(可剥夺式,preemptive):就绪队列中一旦有某进程的优先级高于当前正在执行的进程的优先级时,操作系统便立即进行进程调度,完成进程切换。
  • 不可抢占式(不可剥夺式non_preemptive):即使在就绪队列存在有某进程优先级高于当前正在执行的进程的优先级时,当前进程仍将占用处理机执行,直到该进程自己进入阻塞状态,或时间片用完,或在执行完系统调用后准备返回用户进程前的时刻,才重新发生调度让出处理机。

显然,可抢占式调度可有效减少等待时间和响应时间,但会带来较大的其他管理开销,使得吞吐量等的性能指标比不可抢占式调度要低。所以一般在桌面计算机中都支持可抢占式调度,使得用户可以得到更好的人机交互体验,而在服务器领域不必非要可抢占式调度,而通常会采用不可抢占式调度,从而可提高系统的整体吞吐量。

进程调度的策略/算法

在早期操作系统的调度方式大多数是非剥夺的,这是由于早期的应用一般是科学计算或事务处理,不太把人机交互的响应时间指标放在首要位置。在这种情况下,正在运行的进程可一直占用CPU直到进程阻塞或终止。这种方式的调度算法可以很简单,且比较适用对于响应时间不关心或者关心甚少的批处理科学计算或事务处理应用。随着计算机的应用领域进一步扩展,计算机更多地用在了多媒体等人机交互应用上,为此采用可抢占式的调度方式可在一个进程终止或阻塞之前就剥夺其执行权,把CPU尽快分配给另外的“更重要”进程,使得就绪队列中的进程有机会响应它们用户的IO事件。基于这两种方式的调度算法如下:

  • 先来先服务(FCFS)调度算法:处于就绪态的进程按先后顺序链入到就绪队列中,而FCFS调度算法按就绪进程进入就绪队列的先后次序选择当前最先进入就绪队列的进程来执行,直到此进程阻塞或结束,才进行下一次的进程选择调度。FCFS调度算法采用的是不可抢占的调度方式,一旦一个进程占有处理机,就一直运行下去,直到该进程完成其工作,或因等待某一事件而不能继续执行时,才释放处理机。操作系统如果采用这种进程调度方式,则一个运行时间长且正在运行的进程会使很多晚到的且运行时间短的进程的等待时间过长。

  • 短作业优先(SJF)调度算法:其实目前作业的提法越来越少,我们姑且把“作业”用“进程”来替换,改称为短进程优先调度算法,此算法选择就绪队列中确切(或估计)运行时间最短的进程进入执行。它既可采用可抢占调度方式,也可采用不可抢占调度方式。可抢占的短进程优先调度算法通常也叫做最短剩余时间优先(Shortest Remaining Time First,SRTF)调度算法。短进程优先调度算法能有效地缩短进程的平均周转时间,提高系统的吞吐量,但不利于长进程的运行。而且如果进程的运行时间是“估计”出来的话,会导致由于估计的运行时间不一定准确,而不能实际做到短作业优先。

  • 时间片轮转(RR)调度算法:RR 调度算法与FCFS 调度算法在选择进程上类似,但在调度的时机选择上不同。RR调度算法定义了一个的时间单元,称为时间片(或时间量)。一个时间片通常在1~100 ms之间。当正在运行的进程用完了时间片后,即使此进程还要运行,操作系统也不让它继续运行,而是从就绪队列依次选择下一个处于就绪态的进程执行,而被剥夺CPU使用的进程返回到就绪队列的末尾,等待再次被调度。时间片的大小可调整,如果时间片大到让一个进程足以完成其全部工作,这种算法就退化为FCFS调度算法;若时间片设置得很小,那么处理机在进程之间的进程上下文切换工作过于频繁,使得真正用于运行用户程序的时间减少。时间片可以静态设置好,也可根据系统当前负载状况和运行情况动态调整,时间片大小的动态调整需要考虑就绪态进程个数、进程上下文切换开销、系统吞吐量、系统响应时间等多方面因素。

  • 高响应比优先(Highest Response Ratio First,HRRF)调度算法:HRRF调度算法是介于先来先服务算法与最短进程优先算法之间的一种折中算法。先来先服务算法只考虑进程的等待时间而忽视了进程的执行时间,而最短进程优先调度算法只考虑用户估计的进程的执行时间而忽视了就绪进程的等待时间。HRRF调度算法二者兼顾,既考虑进程等待时间,又考虑进程的执行时间,为此定义了响应比(Rp)这个指标:

    Rp=(等待时间+预计执行时间)/执行时间=响应时间/执行时间
    上个表达式假设等待时间与预计执行时间之和等于响应时间。HRRF调度算法将选择Rp最大值的进程执行,这样既照顾了短进程又不使长进程的等待时间过长,改进了调度性能。但HRRF调度算法需要每次计算各各个进程的响应比Rp,这会带来较大的时间开销(特别是在就绪进程个数多的情况下)。

  • 多级反馈队列(Multi-Level Feedback Queue)调度算法:在采用多级反馈队列调度算法的执行逻辑流程如下:

  1. 设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二队次之,其余队列优先级依次降低。仅当第1~i-1个队列均为空时,操作系统调度器才会调度第i个队列中的进程运行。赋予各个队列中进程执行时间片的大小也各不相同。在优先级越高的队列中,每个进程的执行时间片就越小或越大(Linux-2.4内核就是采用这种方式)。
  2. 当一个就绪进程需要链入就绪队列时,操作系统首先将它放入第一队列的末尾,按FCFS的原则排队等待调度。若轮到该进程执行且在一个时间片结束时尚未完成,则操作系统调度器便将该进程转入第二队列的末尾,再同样按先来先服务原则等待调度执行。如此下去,当一个长进程从第一队列降到最后一个队列后,在最后一个队列中,可使用FCFS或RR调度算法来运行处于此队列中的进程。
  3. 如果处理机正在第i(i>1)队列中为某进程服务时,又有新进程进入第k(k<i)的队列,则新进程将抢占正在运行进程的处理机,即由调度程序把正在执行进程放回第i队列末尾,重新将处理机分配给处于第k队列的新进程。
    从MLFQ调度算法可以看出长进程无法长期占用处理机,且系统的响应时间会缩短,吞吐量也不错(前提是没有频繁的短进程)。所以MLFQ调度算法是一种合适不同类型应用特征的综合进程调度算法。
  • 最高优先级优先调度算法:进程的优先级用于表示进程的重要性及运行的优先性。一个进程的优先级可分为两种:静态优先级和动态优先级。静态优先级是在创建进程时确定的。一旦确定后,在整个进程运行期间不再改变。静态优先级一般由用户依据包括进程的类型、进程所使用的资源、进程的估计运行时间等因素来设置。一般而言,若进程需要的资源越多、估计运行的时间越长,则进程的优先级越低;反之,对于I/O bounded的进程可以把优先级设置得高。动态优先级是指在进程运行过程中,根据进程执行情况的变化来调整优先级。动态优先级一般根据进程占有CPU时间的长短、进程等待CPU时间的长短等因素确定。占有处理机的时间越长,则优先级越低,等待时间越长,优先级越高。那么进程调度器将根据静态优先级和动态优先级的总和现在优先级最高的就绪进程执行。

操作系统中为了能够让每个进程都有机会运行,需要给每个进程分配一个时间片,当一个进程的时间片用完以后,操作系统的调度器就会让当前进程放弃CPU,而选择另外一个进程占用CPU执行。为了有效地支持进程调度所需的时间片,ucore设计并实现了一个timer(计时器)功能。这样,通过timer就对基于时间事件的调度机制提供了基本支持。

算法详解

先来先服务(FCFS)调度算法

先来先服务,是一种简单的调度算法,它既适用于作业调度,也适用于进程调度。先来先服务算法是按照作业或进程到达的先后次序来进行调度。当作业调度中采用该算法时,每次调度都是从后备队列中选择一个最先进入该队列中作业,将它调入内存,为其创建进程、分配相应的资源,将该作业的进程放入就绪队列。在进程调度中采用该算法时,每次调度是从就绪队列中选择一个最新进入该队列的进程,并给他分配处理机。
先来先服务调度算法

进程(作业)名 到达时间(开始时间) 运行时间 结束时间 周转时间
P1 0 9 9 20
P2 0.4 4 13 5
P3 1 1 14 1
P4 5.5 4 18 6
P5 7 2 20 2

先来先服务调度算法分析

时间/s 进程分析
0 P1到达,P1执行(期间执行9s)
0.4 P2到达,P2未执行,P1执行中(剩余8.6s)
1 P3到达,P2未执行,P3未执行,P1(剩余7.6s)
5.5 P4到达,P2未执行,P3未执行,P1(剩余3.5s)
7 P5到达,P5未执行,P4未执行,P2未执行,P3未执行,P1(剩余2s)
9 P1 结束 ,P2开始运行(期间执行4s)
13 P2 结束 ,P3开始运行(期间执行1s)
14 P3 结束 ,P4开始运行(期间执行4s)
18 P4 结束 ,P5开始运行(期间执行2s)
20 P4 结束

需要提出的一点,这个调度算法的调度过程是先找作业或者进程中最先到来的那一个,也就是说,这个是看到达时间的,到达时间越早,则最先进行调度,值得注意的是,此调度算法是服务完一个作业或进程后,再服务下一个作业或者进程。

优点:有利于长作业以及CPU繁忙的作业
缺点:不利于短作业以及I/O繁忙的作业

短作业优先(SJF)调度算法

短作业优先调度算法(Shortest Job First,SJF)或短进程调度算法(Shortest Process First,SPF)是指对短作业或短进程优先调度的算法 。这里,作业或进程的长短是以作业或进程要求运行时间的长短来衡量的。

短作业(进程)优先调度算法

进程(作业)名 到达时间(开始时间) 运行时间 结束时间 周转时间
P1 0 9 20 20
P2 0.4 4 5.4 5
P3 1 1 2 1
P4 5.5 4 11.5 6
P5 7 2 9 2

短作业(进程)优先调度算法分析

时间/s 进程分析
0 P1到达,P1执行
0.4 P2到达,P2执行,P1停(剩余8.6s)
1 P3到达,P2停(剩余3.4s),P3执行
2 P3 结束 ,P2执行
5.4 P2 结束 ,P1执行
5.5 P4到达,P1停(剩余8.5s),P4运行
7 P5到达,P5运行,P4停(剩余2.5s)
9 P5 结束 ,P4运行
11.5 P4 结束 ,P1运行
20 P1 结束

值得注意的时,短作业作业(进程)优先调度算法的确是按照运行时间的长短来衡量的。也就是谁的运行时间短,就先调度哪一个作业或进程。但是,这并不意味着是先把最先调度的那一个作业或进程运行完毕后调度其他的作业或进程,真正的调度过程是交叉进行的。总的顺序还是按照到达的时间开始从最先到达的作业或进程开始进行调度,例如在本例中,P1到达后,立即执行,在P1调度完成之前,P2开始到达,立即执行(此时,P1停止),依次类推。上述表-短作业(进程)优先调度算法分析 相信说的已经足够清楚。

优点:
   1.比FCFS改善平均周转时间和平均带权周转时间,缩短作业的等待时间;
   2.提高系统的吞吐量;
缺点:
   1.对长作业非常不利,可能长时间得不到执行;
   2.未能依据作业的紧迫程度来划分执行的优先级;
   3.难以准确估计作业(进程)的执行时间,从而影响调度性能。

时间片轮转(RR)调度算法

时间片轮转法(Round-Robin,RR算法)主要用于分时系统中的进程调度。
轮转调度的实现原理为系统把所有就绪进程按先入先出的原则排成一个队列,新来的进程就绪队列末尾,每当执行进程调度时,就绪队列的队首进程总是先被调度程序选中,在CPU上运行一个时间片后,系统的计时器发出时钟中断,调度程序进行调度,停止该进程的运行,并把它放入就绪队列的末尾;随后,进行进程切换,把CPU分给就绪队列队首进程,同样让它运行一个时间片,如此往复。轮转法的原理图如下。

以下表来说,其中时间片长度为2ms。

进程(作业)名 到达时间 运行时间 开始时间 结束时间 周转时间
A 0 10 0 30 30
B 0 6 2 22 20
C 0 2 4 6 2
D 0 4 6 16 10
E 0 8 8 28 20
   A   B     C   D    E    A     B   D    E    A     B   E    A     E   A
|————|————|————|————|————|————|————|————|————|————|————|————|————|————|————|————>
0    2    4    6    8   10    12   14   16   18   20   22   24   26   28   30

在这个算法中,可以把时间片轮转法看作一个队列,在队列前面的先进行调度,但是和先来先服务算法不同是,各个进程是交叉进行的。而在先来先服务算法中则是 在调度完成一整个作业(进程) 后,再去调度其他的作业或者进程。从上面的时间轴可以看出,都在一个时间片大小的时间里(这里是2ms)进行调度,一直到一个进程调度完成,从上面的时间轴上还可以清楚的得出,每个进程的到达时间和开始时间也是不一样的。这一点和前面的几种算法也是稍微有区别。
在这里插入图片描述
当同时到达时
老进程先返回:


新进程先进入:
在这里插入图片描述
在这里插入图片描述

- 进 程 切 换 时 机 
      时 间 片 尚 未 用 完 , 进 程 己 完 成 
      时 间 片 己 经 用 完 , 进 程 未 完 成 
- 时 间 片 的 大 小 
         时 间 片 小 利 于 短 作 业 , 但 大 量 中 断 和 切 换 会 增 
    加 系 统 开 销 
         时 间 片 大 减 少 屮 断 和 切 换 , 但 可 能 退 化 为 FCFS , 
   无 法 满 足 交 互 要 求 
         应 使 时 间 片 略 人 于 一 次 典 型 交 互 所 需 时 间 , 以 
   保 证 大 部 分 进 程 在 一 个 时 间 片 完 成 

高响应比优先(HRRF)调度算法

高响应比优先调度算法为每一个作业引入一个动态优先级,即优先级是可以改变的,令他随等待时间延长而增加,这将使长作业的优先级在等待期间不断的增加,等到足够的时间后,必然会有机会获得处理机。该优先级变化规律为:
    优先级 = (等待时间+要求服务时间)/要求服务时间
由于等待时间与服务时间之和就是系统对该作业的响应时间,故该优先级又相当于响应比Rp。优先级又可表示为:

优先级 = (等待时间+要求服务时间)/要求服务时间 = 响应时间/要求服务时间
由上式可以看出

  • 如果作业的等待时间相同,则要求服务的时间愈短,其优先级愈高,因而类似于SJF算法,有利于短作业。
  • 当要求服务的的时间相同时,作业的优先级又取决于其等待时间,因而又类似于FCFS算法。
  • 对于长作业的优先级,可以随等待时间的增加而增大,当其等待时间足够长时,也可获得处理机。
  • 在每次进行调度前,都需要进行响应比的计算,显然会增加系统开销。

案例: 某流水线负责生产汽车玩具的车轮,车盖,车身和座位(两人座),其中车身,车盖,座位,车轮生产时间分别为80s,50s,20s,10s。车轮,车身,座位生产原料相继隔5 秒到达,车盖原料在车轮生产后10s到达。只有一条流水线。为了提高成品的生产效率,应该如何安排零件的生产顺序?

解决步骤:

  1. 车轮最先到达,生产时间最短,所以先生产;车轮在流水线第一生产次序,5秒后到达的车身、座位原料等待5s
  2. 计算车身,座位优先权:

在这里插入图片描述
在这里插入图片描述

由于1.6025>1.25,车身生产次序排第二 此时车盖原料等待80s,座位原料等待5+80=85s

  1. 计算车盖、座位优先权:

高响应比优先调度算法5.png

高响应比优先调度算法6.png

由于5.25>2.6,座位生产次序排第三

  1. 车盖在流水线第四生产次序

在这个解决方案中,生产车轮,车盖,车身和座位就是四个任务,这四个任务到达先后顺序不同,任务执行的时间也不相同。车轮因为先到,就先被生产了,后面等待的车身和座位谁先执行,就由等待时间与生产时间两个因素决定,原则上,等待时间相对生产时间越大的,优先被生产,这就体现在第2步中优先级的计算中,这种优先级的计算就体现了等待时间越长,优先级越高的思想。

多级反馈队列(MFFP)调度算法

引 入 原 因
前 述 方 法 中 , OS 只 设 置 一 个 就 绪 队 列 , 因 此 其 进 程 调 度
算 法 只 有 一 种 , 这 些 定 单 一 的 方 法 无 法 满 足 多 川 尸 的
不 同 要 求
多级反馈队列调度算法是目前操作系统调度算法中被公认的一种较好的调度算法。它可以满足各种类型进程的需要,既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。
解 决 办 法
多 队 列 调 度 算 法
就 绪 队 列 不 止一个 , 同 类 或 同 性 质 的 进 程 在 同 一 队 列 , 每
个 队 列 都 可 以 单 独 置 进 程 优 先 级 的 计 算 公 式
不 同 就 绪 队 列 采 用 不 同 调 度 算 法 和 优 先 级
应 用 领 域
多 处 理 器 系 统 : 每 个 处 理 器 一 个 单 独 的 就 绪 队 列
多 用 户 糸 统 : 根 不 同 用 户 进 程 的 需 求 提 供 多 种 调 度 策略
在这里插入图片描述
· 新 进 程 进 入 内 存 后 , 按 照 FCFS 原 则 放 入 第 一 个 队 列 末 尾 等 待 调 度 , 在 其 时 间 片 内 , 若 能 完 成 任 务 就 撤 离 系 统 , 若 不 能 完 成 就 将 其 优 先 权 降 低 一 个 档 次 , 放 入 第 二 个 队 列 的 队 尾 等 待 调 度 , 如 此 循 环 , 直 到 降 入 第 n 个 ( 最 后 一 个 ) 队 列 后 ,便 在 该 队 列 中 以 时 间 片 轮 转 方 式 运 行

  • 仅 当 第 一 队 列 空 闲 时 , 调 度 程 序 才 会 调 度 第 二 队 列 屮 的 进 程 运 行 , 仅 当 第 1 一 (i-l) 队 列 均 空 闲时 , 才 调 度 第 i 队 列 的 进 程 运 行
  • 在 采 用 抢 占 式 调 度 算 法 的 模 型 中 , 若 第 i 队 列 的 进 程 正 在 执 行 时 , 有 优 先 级 较 高 的 进 程 进 人 高 优 先 权 队 列 , 则 新 进 程 抢 占 当 前 进 程 的 CPU , 并 迫 使 其 回 到 第 i 队 列 的 队 尾 排 队 等 待 下 次 调 度

在这里插入图片描述

最高优先级优先调度算法

分 类

  • 非 抢 占 式 优 先 级 调 度 算 法
    当 前 最 高 优 先 级 进 程 一 直 运 行 至 结 东 或 主 动 放 弃
  • 抢 占 式 优 先 级 调 度 算 法
    当 前 最 高 优 先 级 进 程 执 行 期 间 , 有 更 高 优 先 级 进
    程 到 达 就 要 让 出 CPU
    优 先 级 调 度 算 法 的 关 键 在 于 使 用 静 态 优 先 权
    还 是 动 态 优 先 权 以 及 如 何 确 定 进 程 的 优 先 权
    ( 优 先 数 )

优 先 权 类 型

  • 静 态 优 先 权 : 进 程 创 建 时 确 定 且 在 进 程 生 命 期
    中 保 持 小 变 , 这 种 方 法 实 现 简 单 、 开 销 小 但 小 精
    确 , 可 能 会 产 生 低 优 先 权 进 程 饥 饿 , 用 于 低 要 求
    的 OS
  • 动 态 优 先 权 : 进 程 创 建 时 确 定 的 优 先 数 可 能 陌
    进 程 发 展 或 等 待 时 间 增 加 等 因 素 而 变 化 , 确 保 了
    更 优 良 的 调 度 性 能
    优先权
    确 定 优 先 权 的 依 据
  • 进 程 类 型 : 系 统 进 程 高 于 用 户 进 程
  • 进 程 对 资 源 的 需 求 : 对 系 统 资 源 的 需 求 量 小 的
    进 程 可 以 优 先 运 行
  • 用 户 要 求 : 根 据 用 户 进 程 紧 迫 程 度 和 用 户 所 付
    费 用 决 定 优 先 权
    在这里插入图片描述
    在这里插入图片描述

小结

在这里插入图片描述

w:花费等待的时间
e:到现在为止执行所用的时间
s:进程所需要的总的服务时间

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章