在了解Linux操作系统下的调度算法前,先来谈谈什么是进程调度以及基本的进程调度算法。
▲进程调度:无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
▲进程调度具有四条基本属性和三个基本状态:
基本属性------>1、多态性 从诞生、运行,直至消灭;2、多个不同的进程可以包括相同的程序;3、三种基本状态 它们之间可进行转换;4、并发性并发执行的进程轮流占用处理器。
基本状态------>1、等待态:等待某个事件的完成; 2、就绪态:等待系统分配处理器以便运行;3、运行态:占有处理器正在运行。
★进程调度算法:操作系统对于调度策略所规定的算法以此来实现资源的合理分配。
抢占式(剥夺式)和非抢占式(非剥夺式):
非抢占式/非剥夺式:分派程序一旦把处理机分配给某进程后便让它一直运行下去,直到进程完成或发生。
抢占式/剥夺式:当一个进程正在运行时,系统可以基于某种原则,剥夺已分配给它的处理机,将之分配给其它进程。剥夺原则有:优先权原则、短进程优先原则、时间片原则。
衡量进程调度性能的指标有:周转时间、响应时间、CPU-I/O执行期。
操作系统中基本的调度算法大致可分为六类:
⑴先到先服务算法(FCFS:first come first service):如果早就绪的进程排在就绪队列的前面,迟就绪的进程排在就绪队列的后面,那么该算法总是把当前处于就绪队列之首的那个进程调度到运行状态。也就说,它只考虑进程进入就绪队列的先后,而不考虑它的下一个CPU周期的长短及其他因素。FCFS算法简单易行,是一种非抢占式策略,但性能却不大好。因为对于进程越长时越有利,且对于频繁调用CPU的进程有利,而对于频繁调用I/O接口的进程不利。
⑵短进程优先算法(SJF:Shortest Job First或SPN:Shortest Process Next):对预计执行时间短的进程优先分派处理机。通常后来的短进程不抢先正在执行的进程。其目标是减少平均周转时间。该算法的优点在于比FCFS改善平均周转时间和平均带权周转时间,缩短作业的等待时间;提高系统的吞吐量;但依然存在对长作业非常不利,可能长时间得不到执行;未能依据作业的紧迫程度来划分执行的优先级;难以准确估计作业(进程)的执行时间,从而影响调度性能的缺点。
⑶时间片轮转算法(RR:Round Robin):该算法的特性是让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。其过程:①将系统中所有的就绪进程按照FCFS原则,排成一个队列;②每次调度时将CPU分派给队首进程,让其执行一个时间片。时间片的长度从几个ms到几百ms;③在一个时间片结束时,发生时钟中断;④调度程序据此暂停当前进程的执行,将其送到就绪队列的末尾,并通过上下文切换执行当前的队首进程;⑤进程可以未使用完一个时间片,就让出CPU(如阻塞)。
⑷多级反馈队列算法(Round Robin with Multiple Feedback):该算法是轮转算法和优先级算法的综合和发展。其过程:①设置多个就绪队列,分别赋予不同的优先级,如逐级降低,队列1的优先级最高。每个队列执行时间片的长度也不同,规定优先级越低则时间片越长,如逐级加倍;②新进程进入内存后,先投入队列1的末尾,按FCFS算法调度;若按队列1一个时间片未能执行完,则降低投入到队列2的末尾,同样按FCFS算法调度;如此下去,降低到最后的队列,则按“时间片轮转”算法调度直到完成;③仅当较高优先级的队列为空,才调度较低优先级的队列中的进程执行。如果进程执行时有新进程进入较高优先级的队列,则抢先执行新进程,并把被抢先的进程投入原队列的末尾。该算法拥有①为提高系统吞吐量和缩短平均周转时间而照顾短进程;②获得较好的I/O设备利用率和缩短响应时间而照顾I/O型进程;③不必估计进程的执行时间,动态调节的优点。
⑸优先级算法(Priority Scheduling):该算法是多级队列算法的改进,平衡各进程对响应时间的要求。适用于作业调度和进程调度,可分成抢先式和非抢先式。该算法分为静态优先级和动态优先级。
⑹最高响应比优先法(HRN,Highest Response_ratio Next):该算法是对FCFS方式和SJF方式的一种综合平衡。FCFS方式只考虑每个作业的等待时间而未考虑执行时间的长短,而SJF方式只考虑执行时间而未考虑等待时间的长短。因此,这两种调度算法在某些极端情况下会带来某些不便。HRN调度策略同时考虑每个作业的等待时间长短和估计需要的执行时间长短,从中选出响应比最高的作业投入执行。
响应比R定义如下: R =(W+T)/T = 1+W/T
其中T为该作业估计需要的执行时间,W为作业在后备状态队列中的等待时间。每当要进行作业调度时,系统计算每个作业的响应比,选择其中R最大者投入执行。这样,即使是长作业,随着它等待时间的增加,W / T也就随着增加,也就有机会获得调度执行。这种算法是介于FCFS和SJF之间的一种折中算法。由于长作业也有机会投入运行,在同一时间内处理的作业数显然要少于SJF法,从而采用HRN方式时其吞吐量将小于采用SJF 法时的吞吐量。另外,由于每次调度前要计算响应比,系统开销也要相应增加。
以上就是对所有计算机操作系统进程/作业调度及常用算法概括总结,但对于Linux操作系统来说,其基础的理念相差无几,但是表示略有些许差异。在Linux系统中,每个进程所对应的PCB块中存在一个task_struct结构体,其中有policy、priority、counter、rt_priority这四项,这是作为系统在可执行状态下选择最值得运行进程投入运行的标志项。
⑴policy是进程的调度策略,用来区分实时进程和普通进程,实时进程优先于普通进程运行;
⑵priority是进程(包括实时和普通)的静态优先级;
⑶counter是进程剩余的时间片,它的起始值就是priority的值;由于counter在后面计算一个处于可运行状态的进程值得运行的程度goodness时起重要作用,因此,counter也可以看作是进程的动态优先。
⑷rt_priority是实时进程特有的,用于实时进程间的选择。
Linux系统中的进程调度策略主要分为三种:
1、SCHED_OTHER 分时调度策略;
2、SCHED_FIFO实时调度策略,先到先服务;
3、SCHED_RR实时调度策略,时间片轮转。
实时进程将得到优先调用,实时进程根据实时优先级决定调度权值,分时进程则通过nice和counter值决定权值,nice越小,counter越大,被调度的概率越大,也就是曾经使用了cpu最少的进程将会得到优先调度。
SHCED_RR和SCHED_FIFO的不同:当采用SHCED_RR策略的进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。
如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO时必须等待该进程主动放弃后才可以运行这个优先级相同的任务。而RR可以让每个任务都执行一段时间。