清华大学操作系统公开课(七)处理机调度

1.背景


  上一章介绍了进程都希望获得CPU继续执行,这就涉及到上下文切换:

  •   切换CPU的当前任务,从一个进程/线程到另一个
  •   保存当前进程/线程在PCB/TCB中的执行上下文(CPU状态)
  •   读取下一个进程/线程的上下文

  操作系统要在某个时刻选择哪个进程占用CPU资源,使得计算机效率最高或者满足某些进程的特殊需求,这样的选择就取决与不同的CPU调度策略。

  CPU调度是,从就绪队列中挑选一个进程/线程作为CPU将要运行的下一个进程/线程

  调度程序是,挑选进程/线程的内核函数(通过一些调度策略)

什么时候进行调度?

  结合上一章讲的进程/线程生命周期可以看出,从一个状态向另一个状态变化的时候,其实会触发一次调度,尤其是和运行态相关的状态变化时。

内核运行调度程序的条件(满足一条即可)

  •   一个进程从运行状态切换到等待状态
  •   一个进程被终结了

  调度程序分为两种方式:不可抢占调度和可以抢占调度

  不可抢占:调度程序必须等待时间结束,这样效率上来说很不高,比如有一个进程需要等到读写文件整个过程都完成了以后才会去执行后面的进程。

  可以抢占:用户感觉不到,操作系统决定在某段时刻选择一个进程执行,在下段时刻切换到另一个进程执行。

  •   调度程序在中断被响应后执行
  •   当前的进程从运行切换到就绪,或者一个进程从等待切换到就绪
  •   当前运行的进程可以被换出  

  早期的windows其实不支持用户进程的抢占,但现在linux支持在用户态和内核态都可以抢占,操作系统变得更加灵活和高效。

2.调度原则


  说到操作系统在不同的时间段调度不同的进程执行,那么选择的依据就是调度的原则。

  上图可以看到,在计算机系统中我们看CPU利用率看到的是波动现象。波动现象是指在某些时刻CPU的利用率很高,而在另一些时刻CPU的利用率很低,这是可能存在的,比如执行的进程在某些时刻进行大规模的计算,而后进入I/O的等待,CPU无事可做,CPU利用率显著下降。所以我们希望在当前进程CPU利用率低的时候可以切换到另一个需要CPU大量计算的进程继续执行,这样可以充分利用CPU资源,提高计算机效率。

比较调度算法的指标

  •   CPU利用率:CPU处于忙状态所占时间的百分比。
  •   吞吐量:在单位时间内完成的进程数量。
  •   周转时间:一个进程从初始化到结束,包括所有等待时间所花费的时间,等待时间+服务时间。
  •   等待时间:进程在就绪队列中的总时间。
  •   响应时间:从一个请求被提交到产生第一次响应所花费的时间。

  人们通常需要“更快”的服务,这也是计算机操作系统设计的目的之一。那么什么是更快?

  更快可以是传输文件时的高带宽,也可以是玩游戏时的低延迟,这两个因素是独立的,我们通常不能两项都完美实现,满足一个指标会影响另一个指标,需要寻找调度算法找到平衡。

  举个例子和水管类比一下:

  •   低延迟:喝水的时候想要一打开水龙头水就流出来
  •   高带宽:给游泳池充水时希望从水龙头里同时流出大量的水,并且不介意是否存在延迟

希望调度算法达到的效果

  •   减少响应时间:及时处理用户的输出并且尽快将输出提供给用户
  •   减少平均响应时间的波动:在交互系统中,可预测性比高差异低平均更重要,不会说一会快一会慢
  •   增加吞吐量:希望传文件一下就传完,包含两方面,一是减少开销(操作系统开销,上下文切换);二是系统资源的高效利用(CPU,I/O设备)
  •   减少等待时间:减少每个进程的等待时间

  低延迟调度增加了交互式表现:如果移动了鼠标,但是屏幕中的鼠标没有移动,我可能会重启电脑

  但是操作系统需要保证吞吐量不受影响:我想要结束长时间的编程,所以操作系统必须不时进行调度,即使存在很多交互任务

  可以看出,吞吐量是操作系统的计算带宽,响应时间是操作系统的计算延迟

3.调度算法


  现在常用到的调度算法主要由以下六种,后面会做简单的介绍:

  •  FCFS(First Come,First Served) :先来先服务调度算法
  •  SPN(SJF)  SRT (Shortest Process Next(Shortest Job First) Shortest Remaining Time):短进程优先(短作业优先) 短剩余时间优先
  •   HRRN(Highest Response Ratio Next):最高响应比优先
  •   RR(Round Robin):轮询
  •   Multilevel Feedback Queues:多级反馈队列
  •   Fair Share Scheduling:公平共享调度

 

先来先服务算法(First Come First Served,FCFS)

  先来先服务算法是依据进程进入就绪状态的先后顺序排列,进程进入等待或结束状态时,就绪队列中的下一个进程占用CPU。

  FCFS算法的周转时期:比如上图的三个任务到达顺序是P1,P2,P3依次执行,这样的周转时间计算是(12+15+18)/3=15;如果任务到达顺序是P2、P3、P1依次执行,这样的周转时间计算是(3+6+18)/3=9。

  优点:

  •   简单

  缺点:

  •   平均等待时间波动较大
  •   花费时间少的任务可能排在花费时间长的任务后面:后面的进程会被前面的进程影响。
  •   可能导致I/O和CPU之间的重叠处理:比如说CPU密集型进程会导致I/O设备闲置时,I/O密集型进程也在等待

选择下一个最短的进程算法(短任务优先)

  短任务优先的调度算法是按照预测的完成时间来将任务入队。

  

  短任务优先也有两种实现策略,抢占的和不抢占的。不抢占就是等前面的进程运行完,不打断当前运行的进程,名字是SPN或者SJF就描述的是这种非抢占方式;抢占策略是,已经执行了某个进程一段时间,刚执行完了一个时间片,它还有一个剩余时间段,但此时又来了一个进程,这个进程的剩余时间比执行过进程的剩余时间更小,这时完成一次抢占,把执行的进程从运行态转化为就绪态,让新来的进程占据CPU执行,这就是成为最短剩余时间优先的调度策略,我们成为SRT(shortest remaining time)。

  可以从上面例子中可以看出,根据最短进程优先算法得到的平均周转时间具有最优平均周转时间,而别的排序可能会多出(C4+C6-2C3)这么多等待时间,可以证明这个值一定是大于0的,所以最短进程优先算法获得最优平均周转时间。

  优点:

  根据最短进程优先算法得到的平均周转时间具有最优平均周转时间

  缺点:

  •   可能会导致饥饿:这样的调度算法不能保证每个进程都有一定的机会去占用CPU执行。连续的短任务流会使长任务流饥饿,短任务可用时的任何长任务的CPU时间都会增加平均等待时间
  •   需要预知未来:我们在开始执行一个进程的时候不能预先知道进程的运行时间,就没法根据时间长短排序

  预知未来的解决方法:既然不能知道执行时间,那么可以预估,观察它执行的历史,通过历史情况预估下一时刻的可能时间。

最高响应比优先调度算法(HRRN)

  最高响应比优先调度算法其实是在SPN调度算法基础上的改进,在考虑等待时间的同时也考虑了执行时间,通过等待时间和执行时间计算响应比R,选择就绪队列中响应比R值最高的进程。

  最高响应比优先算法的特点: 

  •   此调度算法一般不抢占
  •   仍然需要通过上面提到的预知未来的解决方式,用历史的执行时间预估未来的执行时间

时间片轮询算法(Round Robin,RR)

  时间片轮询算法其实就是让各进程轮流占用时间片来执行。在叫做时间切片(时间量子)的离散单元中分配处理器,当时间片结束时,切换到下一个准备好的进程。

  时间片是20的RR算法示例:

  从示例中可以看出,把每个进程按时间片最大20为单位做切割(不到20大小当作一个单位),然后依次先入先出执行,P1先执行完20时间片后加入队尾,在68~88和112~115的时刻继续执行,等待时间的计算公式如上图所示,而P2因为执行时间较短在第一个时间片就执行完毕了。这种调度方式使得每一个进程都有机会执行,可以用等待时间来衡量此调度算法的效率,RR的平均等待时间一般是比较大的。

  RR算法的特点:

  •   花销:因为比较频繁地切换,就多出了额外的上下文切换开销
  •   时间切片太大:等待时间过长,在极限情况下会退化成FCFS
  •   时间切片太小:反应迅速,但是吞吐量由于大量的上下文切换开销受到影响

  我们从RR算法的特点可以看出,时间切片的大小选择是一个比较讲究的事情,我们需要选择一个合适的时间切片,已有的经验规则是,早期计算机系统内维持上下文切换开销处于1%s以内,随着计算机的发展,现在需要维持上下文切换开销处于1/1000s内

比较FCFS和RR

  可以看出反而FCFS比RR的平均等待时间会好一点,这也是有道理的,因为FCFS不像RR一样频繁进行进程切换,平均等待时间反而会低一点。但FCFS达不到RR这样能对每个进程及时响应,以及有些情况执行时间长的进程在前面,FCFS的等待时间会比RR更大。

多级队列调度算法(MQ)

  那有没有更好的算法,能够兼顾到RR以及最短进程优先这些算法的特点呢?那就是多级队列调度算法。

  多级队列调度算法的特点:

  •   就绪队列按优先程度被划分成独立的队列:比如说前台注重交互,开销小且需要及时响应,所以优先级比较高;后台完成批处理工作,优先级比较低。
  •   每个队列拥有自己的调度策略:比如说前台使用RR,后台使用FCFS。

多级反馈队列调度算法(MLFQ)

  但是进程是动态的,它的工作特点不是固定的,有可能一个进程的前半段工作主要集中在前台交互,而后半段工作主要集中在后台批处理计算。我们需要一种调度算法考虑到进程的执行特点,来动态调整进程的优先级别。

  可以实现一个多级反馈队列调度算法,可以考虑进程不同时期的执行特点,将进程在不同的队列中移动。

  如图所示,时间片大小随着优先级级别增加而增加,如果任务在当前的时间片中没有完成,则降到下一个优先级。如果进程此段工作是I/O密集型,我们就提高优先级,在等待的数据到达后高优先级队列先处理返回响应;如果进程此段工作是CPU密集型,我们就降低优先级,放在优先级高进程执行完后或者等待时再执行。

公平共享调度(FSS,Fair Share Scheduling)

  这种调度算法重点强调的是公平,因为一个计算机可能服务多个用户,有些用户运行一个进程,有些用户运行多个进程,我们有时需要体现对每个用户的公平性。

  目的:在用户级别做到公平的调用。

 

调度算法总结

  • FCFS 先来先服务:不公平,平均等待时间较差
  • SPN/SRT 短进程优先:不公平,但是平均等待时间最小;需要精确预测计算时间;可能导致饥饿
  • HRRN 最高响应比优先:基于SPN调度改进;不可抢占
  • Round Robin 轮询:公平,但是平均等待时间较差
  • MLFQ 多级反馈队列:与SPN类似
  • Fair-share scheduling 公平共享调度:公平是第一要素

4.多处理器调度


  上面讲到的都是在单个CPU的前提下,怎么调度进程来占用CPU,其实现在我们生活中常遇到的是多处理器(多核)的情况,在这种情况下,怎么利用多CPU来完成有效调度。

  需要考虑以下问题:首先,有多个CPU可以选择,那么有一个进程进来,应该调度到哪个CPU上去执行;其次,有的CPU忙,有的CPU闲,怎么能确保每个CPU负载平衡。  这些需要自己下去了解。

5.优先级反转


  这个名词来源于NASA发射的火星探测装置,在火星运行的时候总是没由来的自动重启,后来经过研究发现是调度算法产生的错误。优先级反转可以发生在任何基于优先级的可抢占调度机制中,当系统内的环境强制使高优先级任务等待低优先级任务时发生。

  可以看看示例,T1的优先级最高,然后是T3和T2。假如刚开始优先级最低的T2执行,同时访问了一块共享资源,这时候T1加入队列并因为优先级高进行抢占,执行过程中也要访问共享资源,发现共享资源还没被T2释放于是进入等待状态,调度T2继续执行并访问共享资源,这时候T3加入队列并因为优先级高进行抢占,此时优先级最高的T1就要等到比自己优先级低的T3执行完以及T2释放资源以后才有机会继续执行。

  简而言之就是,高优先级进程长时间等待低优先级进程占用资源的现象,在NASA火星装置中就是T1总是等待时间过长以为是系统不稳定引起了重启。

  解决方法1:低优先级任务继承高优先级任务的优先级依赖于他们共享的资源。比如例子中的T2本来优先级最低,但由于它占用了和T1的共享资源,就把它的优先级提到和T1一样,这样T3来时不能抢占T2,也就是低优先级进程继承了高优先级进程,使得中优先级进程无法抢占高优先级进程。

  解决方法2:

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值