Linux任务调度机制

作业调度策略:

进程调度在近几个版本中都进行了重要的修改。我们先了解一下进程调度的原理:

(1)进程类型
在linux调度算法中,将进程分为两种类型,即:I/O消耗型和CPU消耗型。例如文本处理程序与正在执行的Make的程序。文本处理程序大部份时间都在等待I/O设备的输入,而make程序大部份时间都在CPU的处理上。因此为了提高响应速度,I/O消耗程序应该有较高的优先级,才能提高它的交互性。相反的,Make程序相比之下就不那么重要了,只要它能处理完就行了。因此,基于这样的原理,linux有一套交互程序的判断机制。在task_struct结构中新增了一个成员:sleep_avg此值初始值为100。进程在CPU上执行时,此值减少。当进程在等待时,此值增加。最后,在调度的时候。根据sleep_avg的值重新计算优先级。
(2)进程优先级
正如我们在上面所说的:交互性强的需要高优先级,交互性弱的需要低优先级。在linux系统中,有两种优先级:普通优先级和实时优先级。我们在这里主要分析的是普通优先级,实时优先级部份可自行了解。
(3)运行时间片
进程的时间片是指进程在抢占前可以持续运行的时间。在linux中,时间片长短可根据优先级来调整。进程不一定要一次运行完所有的时间片。可以在运时的中途被切换出去。
(4)进程抢占
当一个进程被设为TASK_RUNING状态时,它会判断它的优先级是否高于正在运行的进程,如果是,则设置调度标志位,调用schedule()执行进程的调度。当一个进程的时间片为0时,也会执行进程抢占。
 调度程序运行时,要在所有可运行状态的进程中选择最值得运行的进程投入运行。选择进程的依据是什么呢?在每个进程的task_struct结构中有以下四 项: policy、priority、counter、rt_priority。这四项就是调度程序选择进程的依据.其中,policy是进程的调度策略,用来区分两种进程-实时和普通; priority是进程(实时和普通)的优先 级;counter 是进程剩余的时间片,它的大小完全由priority决定;rt_priority是实时优先级,这是实时进程所特有的,用于实时进程间的选择。 

首先,Linux 根据policy从整体上区分实时进程和普通进程,因为实时进程和普通进程度调度是不同的,它们两者之间,实时进程应该先于普通进程而运行,然后,对于同一类型的不同进程,采用不同的标准来选择进程: 

policy的取值会有以下可能:

SCHED_OTHER 分时调度策略,(默认的)
SCHED_FIFO实时调度策略,先到先服务
SCHED_RR实时调度策略,时间片轮转 实时进程将得到优先调用,实时进程根据实时优先级决定调度权值,分时进程则通过nice和counter值决定权值,nice越小,counter越大,被调度的概率越大,也就是曾经使用了cpu最少的进程将会得到优先调度。 
SHCED_RR和SCHED_FIFO的不同:当采用SHCED_RR策略的进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。  
SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有 更高优先级任务到达或自己放弃 。 
如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO时必须等待该进程主动放弃后才可以运行这个优先级相同的任务。而RR可以让每个任务都执行一段时间。
相同点:
RR和FIFO都只用于实时任务。
创建时优先级大于0(1-99)。
按照可抢占优先级调度算法进行。
就绪态的实时任务立即抢占非实时任务。


对于普通进程,Linux采用动态优先调度,选择进程的依据就是进程counter的大小。进程创建时,优先级priority被赋一个初值,一般为 0~70之间的数字,这个数字同时也是计数器counter的初值,就是说进程创建时两者是相等的。 字面上看,priority是"优先级"、 counter是"计数器"的意思,然而实际上,它们表达的是同一个意思-进程的"时间片"。Priority代表分配给该进程的时间片,counter 表示该进程剩余的时间片。在进程运行过程中,counter不断减少,而priority保持不变,以便在counter变为0的时候(该进程用完了所分 配的时间片)对counter重新赋值。当一个普通进程的时间片用完以后,并不马上用priority对counter进行赋值,只有所有处于可运行状态 的普通进程的时间片(p->counter==0)都用完了以后,才用priority对counter重新赋值,这个普通进程才有了再次被调度的 机会。这说明,普通进程运行过程中,counter的减小给了其它进程得以运行的机会, 直至counter减为0时才完全放弃对CPU的使用,这就相对于 优先级在动态变化,所以称之为动态优先调度。至于时间片这个概念,和其他不同操作系统一样的,Linux的时间单位也是"时钟滴答",只是不同操作系统对 一个时钟滴答的定义不同而已(Linux为10ms)。进程的时间片就是指多少个时钟滴答,比如,若priority为20,则分配给该进程的时间片就为 20个时钟滴答,也就是20*10ms=200ms。Linux中某个进程的调度策略(policy)、优先级(priority)等可以作为参数由用户 自己决定,具有相当的灵活性。内核创建新进程时分配给进程的时间片缺省为200ms(更准确的,应为210ms),用户可以通过系统调用改变它。 

对于实时进程, Linux采用了两种调度策略,即FIFO(先来先服务调度)和RR(时间片轮转调度)。因为实时进程具有一定程度的紧迫性,所以衡量一个 实时进程是否应该运行,Linux采用了一个比较固定的标准。实时进程的counter只是用来表示该进程的剩余时间片,并不作为衡量它是否值得运行的标 准。 实时进程的counter只是用来表示该进程的剩余时间片,并不作为衡量它是否值得运行的标准,这和普通进程是有区别的。上面已经看到,每个进程有两 个优先级(动态优先级和实时优先级),实时优先级就是用来衡量实时进程是否值得运行的。 

Linux根据policy的值将进程总体上分为实时进程和普通进程,提供了三种调度算法:一种传统的Unix调度程序和两个由POSIX.1b(原名为 POSIX.4)操作系统标准所规定的"实时"调度程序。但这种实时只是软实时,不满足诸如中断等待时间等硬实时要求,只是保证了当实时进程需要时一定只 把CPU分配给实时进程。 


非实时进程有两种优先级,一种是静态优先级,另一种是动态优先级。实时进程又增加了第三种优先级,实时优先级。优先级是一些简单的整数,为了决定应该允许哪一个进程使用CPU的资源,用优先级代表相对权值-优先级越高,它得到CPU时间的机会也就越大。 

  (1) 静态优先级(priority)-不随时间而改变,只能由用户进行修改。它指明了在被迫和其他进程竞争CPU之前,该进程所应该被允许的时间片的最大值(但很可能的,在该时间片耗尽之前,进程就被迫交出了CPU)。 
  (2)动态优先级(counter)-只要进程拥有CPU,它就随着时间不断减小;当它小于0时,标记进程重新调度。它指明了在这个时间片中所剩余的时间量。 
  (3)实时优先级(rt_priority)-指明这个进程自动把CPU交给哪一个其他进程;较高权值的进程总是优先于较低权值的进程。如果一个进程不是实时进程,其优先级就是0,所以实时进程总是优先于非实时进程的(但实际上,实时进程也会主动放弃CPU)。 

当所有任务都采用FIFO调度策略时(SCHED_FIFO): 
1.创建进程时指定采用FIFO,并设置实时优先级rt_priority(1-99)。 
2.如果没有等待资源,则将该任务加入到就绪队列中。 
3.调度程序遍历就绪队列,根据实时优先级计算调度权值,选择权值最高的任务使用cpu, 该FIFO任务将一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)。 
4.调度程序发现有优先级更高的任务到达(高优先级任务可能被中断或定时器任务唤醒,再或被当前运行的任务唤醒,等等),则调度程序立即在当前任务堆栈中保存当前cpu寄存器的所有数据,重新从高优先级任务的堆栈中加载寄存器数据到cpu,此时高优先级的任务开始运行。重复第3步。 
5.如果当前任务因等待资源而主动放弃cpu使用权,则该任务将从就绪队列中删除,加入等待队列,此时重复第3步。 


当所有任务都采用RR调度策略(SCHED_RR)时: 
1.创建任务时指定调度参数为RR, 并设置任务的实时优先级和nice值(nice值将会转换为该任务的时间片的长度)。 
2.如果没有等待资源,则将该任务加入到就绪队列中。 
3.调度程序遍历就绪队列,根据实时优先级计算调度权值,选择权值最高的任务使用cpu。 
4. 如果就绪队列中的RR任务时间片为0,则会根据nice值设置该任务的时间片,同时将该任务放入就绪队列的末尾 。重复步骤3。 
5.当前任务由于等待资源而主动退出cpu,则其加入等待队列中。重复步骤3。 


系统中既有分时调度,又有时间片轮转调度和先进先出调度: 
1.RR调度和FIFO调度的进程属于实时进程,以分时调度的进程是非实时进程。 
2. 当实时进程准备就绪后,如果当前cpu正在运行非实时进程,则实时进程立即抢占非实时进程 。 
3. RR进程和FIFO进程都采

作业调度算法:
(1)先来先服务算法
(2)段作业优先调度算法
(3)优先级调度算法
(4)时间片轮转调度算法
(5)最高响应比优先调度算法
响应比=周转时间/作业执行时间=(作业执行时间+作业等待时间)/作业执行时间=1+作业等待时间/作业执行时间;
作业周转时间=作业完成时间-作业到达时间
(6)多级反馈队列调度算法
1、进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。
2、首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3三个队列,只有在Q1中没有进程等待时才去调度Q2,同理,只有Q1,Q2都为空时才会去调度Q3。
3、对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。
4、在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(抢占式)。
(7)实时调度算法
A、最早截止时间优先调度算法
B、最低松弛度优先调度算法
种算法是根据任务紧急的程度,来确定任务的优先级。比如说,一个任务在200ms时必须完成而它本身运行需要100ms,所以此任务就必须在100ms之前调度执行,此任务的松弛度就是100ms。在实现此算法时需要系统中有一个按松弛度排序的实时任务就绪队列,松弛度最低的任务排在最烈的最前面,调度程序总是选择就粗队列中的首任务执行!(可理解为最早额定开始)

猜你喜欢

转载自blog.csdn.net/qq_42381849/article/details/92809007