《操作系统概念》笔记--第五章 进程调度

基本概念

CPU调度是多道程序操作系统的基础。通过在进程间切换CPU,操作系统可以使得计算机更加高效。
对于单处理器系统,同一时间只有一个进程可以运行,其他进程都应等待,直到CPU空闲并可调度为止。
多道程序的目标就是,始终允许某个进程运行以最大化CPU利用率。

一个进程执行直到它应等待为止,通常等待某个I/O请求的完成。对于简单的计算机系统,CPU就处于闲置状态。所有这些等待时间就会浪费,没有完成任何有用的工作。
采用多道程序,试图有效利用这些时间。多个进程同时处于内存中,当一个进程等待时,操作系统就从该进程接管CPU控制,并将CPU交给另一个进程。这种方式不断重复。当一个进程必须等待时,另一进程接管CPU使用权。

几乎所有的计算机资源在使用前都要调度,最重要的是CPU调度。

CPU-I/O执行周期

进程执行包括周期(cycle)进行CPU执行和I/O等待。

进程在这两个状态之间不断交替。

进程执行的过程:进程执行从CPU执行(CPU burst)开始,之后I/O执行(I/O burst),接着另一个CPU执行,另一个I/O执行,等等。
最后CPU执行通过系统请求结束,以便终止执行。

CPU调度程序

每当CPU空闲时,操作系统就应从就绪队列中选择一个进程来执行。
进程采用短期调度程序和CPU调度程序。
就绪队列中的记录通常为进程控制快(Procss control block, PCB)

抢占调度

需要进行CPU调度的情况分为以下种:

  1. 当一个进程从运行状态切换到等待状态(如I/O请求,wait()调用)
  2. 当一个进程从运行状态切换到就绪状态(如 当出现中断时)
  3. 当一个进程从等待状态切换到就绪状态(如 I/O完成)
  4. 当一个进程终止时

对于1,4种情况,除了调度没有选择,一个新进程必须被执行。

如果调度只能发生在第1种与第4种情况下,则调度方案称为非抢占的(nonpreemptive)协作的(cooperative),否则,调度方案为抢占的(preemptive)

在非抢占调度下,一旦某个进程分配到CPU,该进程会一直使用CPU,直到它终止或切换到等待状态。

调度程序

调度程序(dispatcher):调度程序是一个模块,用来将CPU控制交给短期调度程序选择的进程。
有下面
三个
功能:

  1. 切换上下文
  2. 切换到用户模式
  3. 切换到用户程序的合适位置,以便重新启动程序。

**调度延迟(dispatch latency):**调度程序停止一个进程而启动另一个所需的时间称为调度延迟。

所以调度程序应尽可能快,因为在每次进程切换时都要使用

调度准则

为了比较CPU调度算法,可以采用许多比较准则。
有以下五种准则:

  1. **CPU使用率:**应使CPU尽可能忙碌。

对于一个实际系统,它的范围应从40%到90%

  1. **吞吐量(throughput):**是一个时间单元内进程完成的数量。

对于长进程,吞吐量可能为每小时一个进程,对于短进程,吞吐量可能为每秒十个进程。

  1. **周转时间(turnaround time):**从进程提交到进程完成的时间段称为周转时间。周转时间为所有时间段之和,包括等待进入内存,在就绪队列中等待,在CPU上执行和I/O执行。
  2. **等待时间:**在就绪队列中等待所花时间之和。

CPU调度算法并不影响进程运行和执行I/O等待时间,它只影响进程在就绪队列中因等待所需的时间。

  1. **响应时间:**从提交请求到产生第一响应的时间。

对于交互系统,响应时间更加重要

一般来说,最大化CPU使用率和吞吐率,并且最小化周转时间,等待时间和响应时间。大多数情况下,优化的是平均值,但是,有些情况需要优化最大值和最小值等。比如交互系统为了保证所有用户都能得到好的服务,可能要使最大响应时间最小。

调度算法

CPU调度处理的问题是,从就绪队列中选择进程以便为其分配CPU。

注意是从就绪队列

先到先服务调度

先到先服务调度算法(First-Come First-Served,FCFS):先请求CPU的进程首先分配到CPU。

最简单的CPU调度算法就是先到先服务调度算法

FCFS策略可以通过FIFO队列实现。
当一个进程进入就绪队列中,它的PCB会被链接到队列尾部。
当CPU空闲时,它会分配给位于队列头部的进程,并且这个运行进程从队列中移去。
缺点是平均等待时间往往很长。
假设有下面一组进程:
图
如果进程按P1,P2,P3的顺序到达,得到如下图
图
平均等待时间为(0+24+27)/3=17ms
但如果按照P2,P3,P1的顺序到达,有如下图
图
平均等待时间为(6+0+3)/3=3ms
可以看出两种情况的平均等待时间相差很大,这是因为护航效果的影响。
**护航效果(convoy effect):**所有其他进程都等待一个大进程释放CPU。

与让较短进程先进行相比,这会导致CPU和设备的使用率降低。

最短作业优先调度

**最短作业优先调度算法(Shortest-Job-First, SJF):**这个算法将每个进程与其下次执行的长度关联起来。当CPU变为空闲时,它会被赋给具有最短CPU执行的进程。

调度取决于下次CPU执行的长度,而不是其总长度

假设有以下一组进程:
图
则调度顺序图为:
图
平均等待时间为(3+16+9+0)/4=7ms
SJF调度算法是最优的,因为它的平均等待时间最小。
但是SJF算法的真正困难是如何知道下次CPU执行的长度。这也导致了SJF调度经常用于长期调度,而不能在短期CPU调度级别上实现

因为没有办法知道下次CPU执行的长度

一种办法就是试图近似SJF调度,如下次CPU执行通常预测为以前CPU执行的测量长度的指数平均(exponential average)
SJF调度可以是抢占的,也可以是非抢占的,抢占的SJF调度也被称为最短剩余时间优先(shortest-remaining-time-first)调度。听名字就很容易理解了。
假设有下面4个进程
图
那么抢占SJF调度执行图为:
图
平均等待时间[(10-1)+(1-1)+(17-2)+(5-3)]/4=6.5ms

进程P1在时间0开始,因为这时候只有进程P1。进程P2在时间1到达。进程P1剩余时间大于进程P2需要的时间,因此进程P1被抢占,而进程P2被调度。

优先级调度

**优先级调度(priority-scheduling):**每个进程都有一个优先级与其关联,而具有最高优先级的进程会分配到CPU。

SJF算法是一个简单的优先级算法,其优先级为下次预测的CPU执行的倒数。CPU执行时间越长,则优先级越小。

假设有以下一组进程:
图
采用优先级调度,按如下顺序进行:
图
平均等待时间为8.2ms
优先调度可以是抢占的或非抢占的。当一个进程到达就绪队列时,比较它的优先级与当前运行进程的优先级。
无穷阻塞(indefinite blocking)饥饿(starvation):这是优先级调度算法的一个主要问题。有时候优先级调度算法会让某个低优先级进程无穷等待CPU。对于一个超载计算机系统,稳定的更高优先级进程流可以阻止低优先级的进程获得CPU。要么进程最终会运行,要么系统最终崩溃并失去所有未完成的低优先级进程。
就绪运行但是等待CPU的进程可以认为是阻塞的
解决方案-老化(aging):逐渐增加在系统中等待很长时间的进程的优先级。

例如,如果优先级从127(低)到0(高),那么每15分钟递减等待进程的优先级的值。最终初始优先级值为127的进程会有系统内最高的优先级,进而能够执行。事实上,不会超过32小时,优先级为127的进程会老化为优先级为0的进程。

轮转调度

**轮转调度算法(Round-Robin, RR):**类似于FCFS调度,但是增加了抢占以切换进程。就绪队列作为循环队列,CPU调度程序循环整个就绪队列,为每个进程分配不超过一个时间片的CPU。
**时间量(tim quantum)或时间片(time slice)😗*一个较小时间单元,大小通常为10~100ms。
RR调度流程:

  1. CPU调度程序从就绪队列中选择第一个进程,将定时器设置在一个时间片后中断,最后分派这个进程。
  2. 如果进程只需少于时间片的CPU执行,进程本身会自动释放CPU,调度程序接着处理就绪队列的下一个进程。
  3. 否则,如果当前运行进程的CPU执行大于一个时间片,那么定时器会中断,进而中断操作系统。然后,进行上下文切换,再将进程加到就绪队列的尾部,接着CPU调度程序会选择就绪队列内的下一个进程。

RR策略的平均等待时间一般较长。假设有以下一组进程:
图
执行过程如下:
图
平均等待时间[(10-4) + (4) + (7)]/3=5.66ms

如果就绪队列有n个进程,并且时间片为q,那么每个进程会得到1/n的CPU时间。而且每次分得的时间不超过q个时间单元。每个进程等待获得下一个CPU时间片的时间不会超过(n-1)q个时间单元
RR算法的性能很大程度上取决于时间片的大小。大多数现代操作系统的时间片为10~100ms,上下文切换的时间一般少于10ms,因此,上下文切换的时间仅占时间片的一小部分。

多级队列调度

**多级队列调度算法(multilevel queue):**将就绪队列分成多个单独队列。根据进程属性,如内存大小,进程优先级,进程类型等,一个进程永久分到一个队列。每个队列有自己的调度算法。队列之间也有调度,通常采用固定优先级抢占调度。

如可有两个队列分别用于前台进程和后台进程。前台队列可以采用RR算法调度,而后台队列可以采用FCFS调度算法

前台进程(foreground process)和后台进程(background process)
进程通常分为前台进程和后台进程。这两种类型的进程具有不同的响应时间要求,进而也有不同调度需要。与后台进程相比,前台进程具有更高的优先级。
下面是一个多级队列调度算法的实例,假设有以下五个队列:(他们的优先级由高到低)

  • 系统进程
  • 交互进程
  • 交互编辑进程
  • 批处理进程
  • 学生进程

每个队列与更低队列相比具有绝对的优先
只有系统进程,交互进程和交互编辑进程队列都为空,批处理队列内的进程才可运行。
如果在一个批处理进程运行时有一个交互进程进入就绪队列,那么该批处理进程会被抢占。

还有一种可能,在队列之间划分时间片
每个队列都有一定比例的CPU时间,可用于调度队列内的进程。
对于前台-后台队列的例子,前台队列可以有80%的CPU时间,用于在进程之间进行RR调度,而后台队列可以有20%的CPU时间,用于按FCFS算法来调度进程。

线程调度

竞争范围

进程竞争范围(System-Contention Scopee, PCS):对于实现多对一和多对多模型的系统线程库会调度用户级线程,以便在LWP(轻量级进程)上运行。

因为竞争CPU是发生在同一进程的线程之间(当我们说线程库将用户线程调度到可用LWP时候,并不意味着线程真实运行在一个CPU上。这会需要操作系统调度内核线程到物理CPU)

系统竞争范围(System-Contention Scope, SCS):为了决定哪个内核级线程调度到一个处理器上,内核采用SCS来竞争CPU,发生在系统内的所有线程之间。

多处理器调度

多处理器调度的方法

非对称多处理器(asymmetric multiprocessing):让一个处理器处理所有调度决定,I/O处理以及其他系统活动,其他的处理器只执行用户代码。

因为只有一个处理器访问系统数据结构,减少了数据共享的需要。

对称多处理器(Symmetric MultiProcessing, SMP):即每个处理器自我调度。所有进程可能处于一个共同的就绪队列中,或每个处理器都有它自己的私有就绪进程队列。

处理器亲和性

  • 考虑一下,当一个进程运行在一个特定处理器时缓存会发生些什么。

进程最近访问的数据更新了处理器的缓存,结果,进程的后续内存访问通常通过缓存来满足。

  • 再考虑一下,如果进程移到其他处理器会发生什么。

第一个处理器的缓存设为无效,第二个处理器缓存应重新填充。并且缓存的无效或重新填充的代价高。
处理器亲和性(processor affinity):一个进程对它运行的处理器具有亲和性,大多数SMP系统试图避免将进程从一个处理器移到另一个处理器,而是试图将一个进程运行在同一个处理器上
软亲和性(soft affinity):一个操作系统试图保持进程运行在同一个处理器上(但不保证他会这么做)
硬亲和性(hard affinity):允许某个进程运行在某个处理器子集上。

负载平衡

对于SMP系统,重要的是保持所有处理器的负载平衡。
负载平衡设法将负载平均分配到SMP系统的所有处理器上。
推迁移(push migration):对于推迁移,一个特定的任务周期性检查每个处理器的负载平衡。如果发现不平衡,那么通过将进程从超载处理器推到空闲或不太忙的处理器上来实现负载平衡
拉迁移(pull migration):空闲处理器从一个忙的处理器上拉一个等待任务

多核处理器

内存停顿(memory stall):当一个处理器访问内存时,它花费大量时间等待所需数据

如高速缓存未命中

粗粒度(coarse-grained):对于粗粒度的多线程,线程一直在处理器上执行,直到一个长延迟事件(如内存停顿)发生。由于长延迟事件造成的延迟,处理器应切换到另一个线程来开始执行。
细粒度(fine-grainded):细粒度的多线程在更细的粒度级别上(通常在指令周期的边界上)切换进程。而且,细粒度系统的架构设计有线程切换的逻辑。所以,线程之间切换成本很小。

实时CPU调度

软实时系统(soft real-time system):不保证会调度关键实时进程,而只保证这类进程会优先于非关键进程。
硬实时进程(hard real-time system):一个任务应该在它的截止期限之前完成,在截止期限之后完成,与没有完成,是一样的。

最小化延迟

事件延迟(event latency):从事件发生到事件得到服务的这段时间
两种类型的延迟影响实时系统的性能:中断延迟和调度延迟
中断延迟(interrupt latency):是从CPU收到中断处理程序开始的时间

当一个中断发生时,操作系统应先完成正在执行的指令,再确定发生中断的类型。然后,应保存当前进程的状态,再采用特定的**中断服务程序(Interrupt Service Routine, ISR)**来处理中断。执行这些任务需要的总时间为中断延迟。

步骤如下:

  • 确定中断类型
  • 上下文切换
  • 采用ISR中断延迟
    调度延迟(dispatch latency):从停止一个进程到启动另一个进程所需的时间量

优先权调度

实时操作系统最重要的功能是:当一个实时进程需要CPU时,立即响应。因此,用于实时操作系统的调度程序应支持抢占的基于优先权的算法。

基于优先权的调度算法根据每个进程的重要性而分配优先级,进程越重要,它分配的优先级也就越高。如果调度程序还需要抢占,并且有一个更高优先级的进程处于就绪,那么正在运行的,较低优先级的进程会被抢占。
提供抢占的,基于优先级的调度算法仅保证软实时功能。
进程是周期性的,一旦周期性进程获得CPU,他具有固定的处理时间t,CPU应处理的截止期限d和周期p。
处理时间,截止期限和周期三者之间的关系为:0<=t<=d<=p。周期任务的速率为1/p。
调度程序可以根据进程的截止期限或速率要求来分配优先级。

图5-15

单调速率调度

单调速率算法采用抢占的,静态优先级的策略,调度周期性任务。
当较低优先级的进程正在运行并且较高优先级的进程可以运行时,较高优先级进程将会抢占低优先级。
在进入系统时,每个周期性任务会分配一个优先级,它与其周期成反比。周期越短,优先级越高,周期越长,优先级越低。
这种策略背后的理由是:更频繁地需要CPU的任务应分配更高的优先级,此外,单调速率调度假定:对于每次CPU执行,周期性进程的处理时间是相同的,也就是说,在每次进程获取CPU时,它的CPU执行长度是相同的。
下面考虑一个例子:
我们有两个进程P1,P2。P1和P2的周期分别为50与100,即P1=50,P2=100,P1和P2的处理时间分别为T1=20和T2=35。每个进程的截止期限要求,它在下一个周期开始之前完成CPU执行。
是否可能调度这些任务以便每个进程都能满足截止期限?
假设P2分配比P1更高的优先级。则执行情况如图
图5-16
P2首先开始执行并在时间35完成。这时P1开始,在CPU执行时间55完成。然而,P1的第一个截止时间是在时间50,所以调度程序让P1错过其截止期限。
假设P1具有更高的优先级,则执行情况如图:
图5-17
首先,P1开始,并在时间20完成,从而满足第一个截止期限。然后P2开始运行,运行到时间50。此时,它被P1抢占,尽管它的CPU执行仍有5ms的时间。P1在时间70完成CPU执行,然后P2恢复,并在75完成CPU执行,也满足第一个截止期限。然后,系统一直空闲直到时间100,这时,P1再次被调度。
单调速率调度可认为是最优的,如果一组进程不能由此算法调度,它不能由任何其他分配静态优先级的算法来调度。
下面是一组不能使用单调速率算法来调度的进程:
P1=50,T1=25,P2=80,T2=35,且P1具有较高的优先级,执行情况如图:
图5-18
最初,P1运行,直到CPU执行时间25完成,进程P2开始运行,运行直到时间50,这时被P1抢占,P1运行到时间75,P2还有10ms的剩余,执行到85。因为超过了时间 80的截止期限。

最早截止期限优先调度

**最早截止期限优先(Earliest-Deadline-First, EDF)**调度根据截止期限动态分配优先级。
截止期限越早,优先级越高;截止期限越晚,优先级越低。
根据PDF策略,当一个进程可运行时,它应向系统公布截止期限要求。优先级可能需要调整,以便反映新可运行进程的截止期限。

与单调速率调度与EDF调度的不同,前者的优先级是固定的

P1=50,T1=25,P2=80,T2=35,执行情况如图:
图5-18
进程P1的截止期限为最早,所以它的初始优先级比P2的要高。
当P1的CPU执行结束时,进程P2开始运行。P2的下个截止期限为80,而P1的下个截止期限为100,所以,P2的优先级更高,可以一直运行到时间60
进程P1在时间60再次开始运行,在时间85完成第二个CPU执行,也满足第二个期限(时间100)。这时,进程P2开始运行,只是在时间100被P1抢占。因为P2的下个截止期限为160,而P1的截止期限为150,所以P1的优先级高。
时间125P2恢复执行,时间145,P2完成执行,满足截止期限。
然后,系统空闲知道时间150,在时间150P1开始再次被调度。

EDF调度在理论上是最佳的,但是在实际中,由于进程的上下文切换和中断处理的代价,这种级别的CPU利用率是不可能的。

比例分享调度

**比例分享(proprotiona share)**调度程序在所有应用之间分配T股,如果一个应用程序接收N股的时间,那么确保了它将有N/T的总的处理器时间。

小结

  1. CPU调度四种情况
  2. 调度程序
  3. 5种调度准则
  4. 5种调度算法
  5. 四种实时CPU调度
    1开始再次被调度。

EDF调度在理论上是最佳的,但是在实际中,由于进程的上下文切换和中断处理的代价,这种级别的CPU利用率是不可能的。

比例分享调度

**比例分享(proprotiona share)**调度程序在所有应用之间分配T股,如果一个应用程序接收N股的时间,那么确保了它将有N/T的总的处理器时间。

小结

  1. CPU调度四种情况
  2. 调度程序
  3. 5种调度准则
  4. 5种调度算法
  5. 四种实时CPU调度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值