常见的及Linux中的进程调度算法

来源:互联网 发布:ui设计 前景 知乎 编辑:程序博客网 时间:2024/06/05 10:59

    首先,我们来看看什么是进程调度。


高级调度:(High-Level Scheduling)又称为作业调度,它决定把后备作业调入内存运行;
低级调度:(Low-Level Scheduling)又称为进程调度,它决定把就绪队列的某进程获得CPU;
中级调度:(Intermediate-Level Scheduling)又称为在虚拟存储器中引入,在内、外存对换区进行进程对换。
接下来,我们看一看常见的进程调度算法。


先来先服务(First Come First Service,FCFS)调度算法按照进程进入就绪队列的先后顺序选择可以占用处理器的进程。这是一种不可抢占方式的调度算法,优点是实现简单,缺点是后来的进程等待CPU的时间较长。它现今主要用作辅助调度法;例如结合在优先级调度算法中使用,当有两个最高优先级的进程时,则谁先来,谁就先被调度。
 
  
短执行进程优先算法(Shortest Process First,SPF)就是从就绪队列中选择一个CPU执行时间预期最短的进程,将处理器分配给它。虽然较公平,但实现难度较大,因为要准确预定下一个进程的CPU执行周期是很困难的。
 
  
•最高优先级优先(Highest Priority First,HPF)调度算法的核心是确定进程的优先级。首先,系统或用户按某种原则为进程指定一个优先级来表示该进程所享有的调度优先权。确定优先级的方法较多,一般可分为两类,即静态法和动态法。静态法根据进程的静态特性,在进程开始执行之前就确定它们的优先级,一旦开始执行之后就不能改变。动态法则不然,它把进程的静态特性和动态特性结合起来确定进程的优先级,随着进程的执行过程,其优先级不断变化。   
•进程的静态优先级确定最基本的方法是按照进程的类型给予不同的优先级。例如,在有些系统中,进程被划分为系统进程和用户进程。系统进程享有比用户进程高的优先级;对于用户进程来说,则可以分为:I/O繁忙的进程、CPU繁忙的进程、I/O与CPU均衡的进程和其他进程等。
•对系统进程,也可以根据其所要完成的功能划分为不同的类型。例如,调度进程、I/O进程、中断处理进程、存储管理进程等。这些进程还可进一步划分为不同类型并赋予不同的优先级。例如,在操作系统中,对于键盘中断的处理优先级和对于电源掉电中断的处理优先级是不相同的。
•基于静态优先级的调度算法实现简单,系统开销小,但由于静态优先级一旦确定之后,直到执行结束为止始终保持不变,从而系统效率较低,调度性能不高。现在的操作系统中,如果使用优先级调度的话,则大多采用动态优先级的调度策略。
•进程的动态优先级一般可以根据以下两个方面来确定:
• (1)根据进程占有CPU时间的长短来决定。一个进程占有处理机的时间愈长,则在被阻塞之后再次获得调度的优先级就越低。反之,其获得调度的可能性就会越大。
• (2)根据就绪进程等待CPU的时间长短来决定。一个就绪进程在就绪队列中等待的时间越长,则它获得调度选中的优先级就越高。
•由于动态优先级随时间的推移而变化,系统要经常计算各个进程的优先级,因此,系统要为此付出一定的开销。
•最高优先级优先调度算法用于多道批处理系统中较好,但它使得优先级较低的进程等待时间较长,这对于分时系统中要想获得较好的响应时间是不允许的,所以在分时系统中多采用时间片轮转法来进行进程调度。


接下来,我们在说一说Linux中的进程调度。

调度程序运行时,要在所有可运行状态的进程中选择最值得运行的进程投入运行。选择进程的依据是什么呢?在每个进程的task_struct结构中有以下四项:policy、priority、counter、rt_priority。这四项是选择进程的依据。其中,policy是进程的调度策略,用来区分实时进程和普通进程,实时进程优先于普通进程运行;priority是进程(包括实时和普通)的静态优先级;counter是进程剩余的时间片,它的起始值就是priority的值;由于counter在后面计算一个处于可运行状态的进程值得运行的程度goodness时起重要作用,因此,counter也可以看作是进程的动态优先级。rt_priority是实时进程特有的,用于实时进程间的选择。
 


调度方法
1,SCHED_OTHER 分时调度策略,
2,SCHED_FIFO实时调度策略,先到先服务
3,SCHED_RR实时调度策略,时间片轮转


相同点:
RR和FIFO都只用于实时任务。
创建时优先级大于0(1-99)。
按照可抢占优先级调度算法进行。
就绪态的实时任务立即抢占非实时任务。
所有任务都采用linux分时调度策略时。
1,创建任务指定采用分时调度策略,并指定优先级nice值(-20~19)。
2,将根据每个任务的nice值确定在cpu上的执行时间(counter)。
3,如果没有等待资源,则将该任务加入到就绪队列中。
4,调度程序遍历就绪队列中的任务,通过对每个任务动态优先级的计算(counter+20-nice)结果,选择计算结果最大的一个去运行,当这个时间片用完后(counter减至0)或者主动放弃cpu时,该任务将被放在就绪队列末尾(时间片用完)或等待队列(因等待资源而放弃cpu)中。
5,此时调度程序重复上面计算过程,转到第4步。
6,当调度程序发现所有就绪任务计算所得的权值都为不大于0时,重复第2步。
所有任务都采用FIFO时,
1,创建进程时指定采用FIFO,并设置实时优先级rt_priority(1-99)。
2,如果没有等待资源,则将该任务加入到就绪队列中。
3,调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu,该FIFO任务将一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)。
4,调度程序发现有优先级更高的任务到达(高优先级任务可能被中断或定时器任务唤醒,再或被当前运行的任务唤醒,等等),则调度程序立即在当前任务堆栈中保存当前cpu寄存器的所有数据,重新从高优先级任务的堆栈中加载寄存器数据到cpu,此时高优先级的任务开始运行。重复第3步。
5,如果当前任务因等待资源而主动放弃cpu使用权,则该任务将从就绪队列中删除,加入等待队列,此时重复第3步。
所有任务都采用RR调度策略时
1,创建任务时指定调度参数为RR,并设置任务的实时优先级和nice值(nice值将会转换为该任务的时间片的长度)。
2,如果没有等待资源,则将该任务加入到就绪队列中。
3,调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu。
4,如果就绪队列中的RR任务时间片为0,则会根据nice值设置该任务的时间片,同时将该任务放入就绪队列的末尾。重复步骤3。
5,当前任务由于等待资源而主动退出cpu,则其加入等待队列中。重复步骤3。
系统中既有分时调度,又有时间片轮转调度和先进先出调度
1,RR调度和FIFO调度的进程属于实时进程,以分时调度的进程是非实时进程。
2,当实时进程准备就绪后,如果当前cpu正在运行非实时进程,则实时进程立即抢占非实时进程。
3,RR进程和FIFO进程都采用实时优先级做为调度的权值标准,RR是FIFO的一个延伸。FIFO时,如果两个进程的优先级一样,则这两个优先级一样的进程具体执行哪一个是由其在队列中的未知决定的,这样导致一些不公正性(优先级是一样的,为什么要让你一直运行?),如果将两个优先级一样的任务的调度策略都设为RR,则保证了这两个任务可以循环执行,保证了公平。


本文仅对进程调度进行了简单的介绍和理解,如有错误,望留言批评。

1 0
原创粉丝点击