pkzd之进程设计策略之进程调度

   本文主要讨论单处理器上的进程调度算法,在讨论具体的算法以前先假设存在一个具体的操做系统好比pkzd。linux

  假设该系统pkzd并不存在抢占进程调度,而后咱们考虑接下来的状况:算法

  •          假设在内存中同时存在进程p1, p2, p3(此处为了方便不讨论进程换出的状况), p1, p2, p3的运行时间分别为10ms, 100ms, 1000ms, 若是系统依次运行进程,那么平均的等待时间约为40ms, 若是进程达到的顺序为p3, p2, p1,那么平均的等待时间约为370ms。进程的平均等待时间由于进程达到的顺序而存在巨大的差距,更有甚者,若是存在一个进程的运行时间为无穷,那么它将占用全部的cpu时间,这明显是不合理的,因此必须引入一种机制来保证公平调度。注: 非抢占式系统存在不少的调度算法,有的算法能缩小由于进程达到顺序不一样而形成的平均等待时间之间的差距,可是有的算法实现并不是很简单,好比SJF算法。另外全部的非抢占式系统都没法很好的处理永远不会终止的进程(好比系统中存在不少的死循环)。shell

  单处理器中进程调度所要达到的目标就是让全部的进程公平的分配cpu时间,咱们先来讨论其中一种比较古老又简单质朴的办法:性能

  •     RR算法,该算法主要的想法是给全部的进程分配一个时间片,一个进程至多占用一个时间片,一旦时间片用完就必须调用其余的进程。能够用链表实现该算法(固然这不是最好的实现办法, 也不必定是最简单的,之因此用链表只是由于本人以为用链表比较简单,不过你不必定这么认为):spa

    • head---p1----p2---p3------pn操作系统

    head指向进程链表的头部,p1, p2至pn表明进程。假设操做系统给每一个进程分配一个固定的时间片10ms(注:该值的大小在用RR算法的系统中对整个操做系统的性能会有很大的影响,该值大小的设定必需要慎重,最后10ms是一个不错的能够考虑的时间片大小的值),而后内核首先调用进程p1,在运行一段时间后(小于等于10ms, 若是进程p1阻塞于某个事件,那么运行事件将小于10ms, 一种极端状况可能为几ns),内核将p1添加到进程链表的尾部,而且从新设置进程p1的时间片为10ms,而后内核继续调用进程p2,就这样内核不停的调用不一样的进程来保证公平。线程

    RR算法简单有效的实现了一种公平的调度机制,不过该算法存在一些问题,好比如下状况:进程

    •     存在进程p一、 p2, 假设p1进程是一个正在运行的shell, p2则是一个暴力破解的程序(可能会运行几天)。首先内核调用进程p1,由于用户没有在键盘输入任何数据因此p1运行1ns就陷入睡眠,而后内核调用p2运行,在运行一段时间后(由于p1在睡眠中,因此运行的程序一直是p2),用户输入一些字符(多是一个命令ls),而后内核唤醒进程p1,等待p2的时间片结束,以后调用p1,p1执行命令ls后继续陷入睡眠(此次执行的时间假设为1ms)。内核就这样周而复始的不断调用p1和p2, 可能你已经发现,在这种状况下p2占用的cpu时间会远远大于p1,这明显是不公平的。另外对于交互式系统,用户老是但愿在按下键的时候获得响应,用户一般不会关心后台进程是否正在运行,因此通常认为交互式进程应该获得更高的优先级以能被尽快调度。事件

  一种改进的机制是加入优先级,实现方式多是按优先级将全部的进程分类,好比等待键盘输入的进程放到类I/O字符中,等待内存的放到类mem中,等待磁盘的放到类I/O块中,内核每次调度都先从I/0字符类(该类的进程通常都和叫魂有关,因此有更高的优先级)开始查找能运行的进程,若是找不到就去下一个类中寻找,最后若是全部的类都不存在可运行的进程,内核就从idle类中找出一个空转进程并运行它。将全部的进程分类的办法可让I/0密集进程等到更公平的对待,而且因为I/O密集进程的大部分时间都在睡眠,因此cpu密集的进程也能获得较好的对待。不过这样的实现一样存在问题:内存

    考虑如下状况,操做系统存在10万个进程,5万个I/O密集进程, 5万个CPU密集进程,那么可能发生一种状况,内核将老是从I/O类中调度进程而不会转入cpu类中,如此将会有5万个进程被不公平的对面,而且可能永远都不会被运行。对于这种状况,一种可能的改进方法是增长一些计数变量来观测全部的进程类,在内核将要调度进程时内核根据计数变量来选择合适的类(好比类中的进程所占用的总的cpu数目,进程数,调度次数等),固然这将是一个复杂的实现。

 接下来讲明一下linux的调度机制,linux与通常的时间片调度算法不一样,它所采用的是一种比例的方法来对全部的进程分配时间片,linux的算法很好的保证了全部进程的一个调度(虽然在进程数目暴增时,它的保证将再也不有效)。

  至于线程调度,这是一个更加复杂的话题,一个简答的例子,对于不一样进程的线程是否要同等对待就是一个值得考虑的问题,由于本文字数有限就不讨论了。

 最后,调度算法对整个操做系统的性能会产生很大的影响,而且对于不一样的进程,内核如何差异对待而且保证公平也是个值得考虑的问题,好比PC上的交互式进程通常状况应该比cpu密集的进程得到更多的调度机会,而一些特殊的状况,好比一个核武器的演算进程应该比一个交互进程得到更多的cpu才对。无论如何调度机制要保证的是全部的进程被公平的对待,对于I/O密集的进程应该保证其运行时间而给予更多的调度次数,而cpu密集的进程应该适当的减小其调度次数来减小其占用cpu的时间。

相关文章
相关标签/搜索