【操作系统】批处理系统和交互式系统中的调度算法

“批处理系统中的调度”

  1. 先来先服务

  2. 最短作业优先

  3. 最短剩余时间优先

    最短作业优先的抢占式版本是最短剩余时间优先(shortest remaining time next)算法。使用这个算法,调度程序总是选择剩余运行时间最短的那个进程运行。再次提醒,有关的运行时间必须提前掌握。当一个新的作业到达时,其整个时间同当前进程的剩余时间做比较。如果新的进程比当前运行进程需要更少的时间,当前进程就被挂起,而运行新的进程。这种方式可以使新的短作业获得良好的服务。

“交互式系统中的调度”

  1. 轮转调度

    一种最古老、最简单、最公平且使用最广的算法是轮转调度(round robin)。每个进程被分配一个时间段,称为时间片(quantum),即允许该进程在该时间段中运行。如果在时间片结束时该进程还在运行,则将剥夺CPU并分配给另一个进程。如果该进程在时间片结束前阻塞或结束,则CPU立即进行切换。时间片轮转调度很容易实现,调度程序所要做的就是维护一张可运行进程列表。当一个进程用完它的时间片后,就被移到队列的末尾。

    时间片轮转调度中惟一有趣的一点是时间片的长度。从一个进程切换到另一个进程是需要一定时间进行管理事务处理的——保存和装入寄存器值及内存映像、更新各种表格和列表、清除和重新调入内存高速缓存等。假如进程切换(process switch),有时称为上下文切换(context switch),需要1ms,包括切换内存映像、清除和重新调入高速缓存等。再假设时间片设为4ms。有了这些参数,则CPU在做完4ms有用的工作之后,CPU将花费(即浪费)1ms来进行进程切换。因此,CPU时间的20%浪费在管理开销上。很清楚,这一管理时间太多了。

    为了提高CPU的效率,我们可以将时间片设置成,比方说,100ms,这样浪费的时间只有1%。但是,如果在一段非常短的时间间隔内到达50个请求,并且对CPU有不同的需求,那么,考虑一下,在一个服务器系统中会发生什么呢?50个进程会放在可运行进程的列表中。如果CPU是空闲的,第一个进程会立即开始执行,第二个直到100ms以后才会启动,以此类推。假设所有其他进程都用足了它们的时间片的话,最不幸的是最后一个进程在获得运行机会之前将不得不等待5秒钟。大部分用户会认为5秒的响应对于一个短命令来说是缓慢的。如果一些在队列后端附近的请求仅要求几毫秒的CPU时间,上面的情况会变得尤其糟糕。如果使用较短的时间片的话,它们将会获得更好的服务。

    另一个因素是,如果时间片设置长于平均的CPU突发时间,那么不会经常发生抢占。相反,在时间片耗费完之前多数进程会完成一个阻塞操作,引起进程的切换。抢占的消失改善了性能,因为进程切换只会发生在确实逻辑上有需要的时候,即进程被阻塞不能够继续运行。

    可以归结如下结论:时间片设得太短会导致过多的进程切换,降低了CPU效率;而设得太长又可能引起对短的交互请求的响应时间变长。将时间片设为20ms~50 ms通常是一个比较合理的折中。

  2. 优先级调度

    每个进程被赋予一个优先级,允许优先级最高的可运行进程先运行。

    即使在只有一个用户的PC机上,也会有多个进程,其中一些比另一些更重要。例如,与在屏幕上实时显示视频电影的进程相比,在后台发送电子邮件的守护进程应该被赋予较低的优先级。

    为了防止高优先级进程无休止地运行下去,调度程序可以在每个时钟滴答(即每个时钟中断)降低当前进程的优先级。如果这个动作导致该进程的优先级低于次高优先级的进程,则进行进程切换。一个可采用的方法是,每个进程可以被赋予一个允许运行的最大时间片,当这个时间片用完时,下一个次高优先级的进程获得机会运行。

    为达到某种目的,优先级也可以由系统动态确定。例如,有些进程为I/O密集型,其多数时间用来等待I/O结束。当这样的进程需要CPU时,应立即分配给它CPU,以便启动下一个I/O请求,这样就可以在另一个进程计算的同时执行I/O操作。使这类I/O密集型进程长时间等待CPU只会造成它无谓地长时间占用内存。使I/O密集型进程获得较好服务的一种简单算法是,将其优先级设为1/f,f为该进程在上一时间片中所占的部分。一个在其50ms的时间片中只使用1ms的进程将获得优先级50,而在阻塞之前用掉25ms的进程将具有优先级2,而使用掉全部时间片的进程将得到优先级1。

    可以很方便地将一组进程按优先级分成若干类,并且在各类之间采用优先级调度,而在各类进程的内部采用轮转调度。图中给出了一个有4类优先级的系统,其调度算法如下:只要存在优先级为第4类的可运行进程,就按照轮转法为每个进程运行一个时间片,此时不理会较低优先级的进程。若第4类进程为空,则按照轮转法运行第3类进程。若第4类和第3类均为空,则按轮转法运行第2类进程。如果不偶尔对优先级进行调整,则低优先级进程很可能会产生饥饿现象。

    在这里插入图片描述

  3. 多级队列

  4. 最短进程优先

    对于批处理系统而言,由于最短作业优先常常伴随着最短响应时间,所以如果能够把它用于交互进程,那将是非常好的。在某种程度上,的确可以做到这一点。交互进程通常遵循下列模式:等待命令、执行命令、等待命令、执行命令,如此不断反复。如果我们将每一条命令的执行看作是一个独立的“作业”,则我们可以通过首先运行最短的作业来使响应时间最短。这里惟一的问题是如何从当前可运行进程中找出最短的那一个进程。

    一种办法是根据进程过去的行为进行推测,并执行估计运行时间最短的那一个。假设某个终端上每条命令的估计运行时间为T0 。现在假设测量到其下一次运行时间为T1 。可以用这两个值的加权和来改进估计时间,即aT0 +(1-a)T1 。通过选择a的值,可以决定是尽快忘掉老的运行时间,还是在一段长时间内始终记住它们。当a=1/2时,可以得到如下序列:

    T0 ,T0 /2+T1 /2,T0 /4+T1 /4+T2 /2,T0 /8+T1 /8+T2 /4+T3 /2

    可以看到,在三轮过后,T0 在新的估计值中所占的比重下降到1/8。

    有时把这种通过当前测量值和先前估计值进行加权平均而得到下一个估计值的技术称作老化(aging)。它适用于许多预测值必须基于先前值的情况。老化算法在a=1/2时特别容易实现,只需将新值加到当前估计值上,然后除以2(即右移一位)。

  5. 保证调度

    一种完全不同的调度算法是向用户作出明确的性能保证,然后去实现它。一种很实际并很容易实现的保证是:若用户工作时有n个用户登录,则用户将获得CPU处理能力的1/n。类似地,在一个有n个进程运行的单用户系统中,若所有的进程都等价,则每个进程将获得1/n的CPU时间。看上去足够公平了。

    为了实现所做的保证,系统必须跟踪各个进程自创建以来已使用了多少CPU时间。然后它计算各个进程应获得的CPU时间,即自创建以来的时间除以n。由于各个进程实际获得的CPU时间是已知的,所以很容易计算出真正获得的CPU时间和应获得的CPU时间之比。比率为0.5说明一个进程只获得了应得时间的一半,而比率为2.0则说明它获得了应得时间的2倍。于是该算法随后转向比率最低的进程,直到该进程的比率超过它的最接近竞争者为止。

  6. 彩票调度

    给用户一个保证,然后兑现之,这是个好想法,不过很难实现。但是,有一个既可给出类似预测结果而又有非常简单的实现方法的算法,这个算法称为彩票调度(lottery scheduling)(Waldspurger和Weihl,1994)。

    其基本思想是向进程提供各种系统资源(如CPU时间)的彩票。一旦需要做出一项调度决策时,就随机抽出一张彩票,拥有该彩票的进程获得该资源。在应用到CPU调度时,系统可以掌握每秒钟50次的一种彩票,作为奖励每个获奖者可以得到20ms的CPU时间。

  7. 公平分享调度

    到现在为止,我们假设被调度的都是各个进程自身,并不关注其所有者是谁。这样做的结果是,如果用户1启动9个进程而用户2启动1个进程,使用轮转或相同优先级调度算法,那么用户1将得到90%的CPU时间,而用户2只得到10%的CPU时间。

    为了避免这种情形,某些系统在调度处理之前考虑谁拥有进程这一因素。在这种模式中,每个用户分配到CPU时间的一部分,而调度程序以一种强制的方式选择进程。这样,如果两个用户都得到获得50%CPU时间的保证,那么无论一个用户有多少进程存在,每个用户都会得到应有的CPU份额。

    作为一个例子,考虑有两个用户的一个系统,每个用户都保证获得50%CPU时间。用户1有4个进程A、B、C和D,而用户2只有1个进程E。如果采用轮转调度,一个满足所有限制条件的可能序列是:

    A E B E C E D E A E B E C E D

    另一方面,如果用户1得到比用户2两倍的CPU时间,我们会有

    A B E C D E A B E C D E…

    当然,大量其他的可能也存在,可以进一步探讨,这取决于如何定义公平的含义。

发布了447 篇原创文章 · 获赞 14 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105549677