操作系统概念第五章笔记

基本概念

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)。

调度程序

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

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

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

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

调度准则

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

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

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

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

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

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

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

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

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

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

调度算法

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

先到先服务调度

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

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

FCFS策略可以通过FIFO队列实现。

当一个进程进入就绪队列中,它的PCB会被链接到队列尾部。
当CPU空闲时,它会分配给位于队列头部的进程,并且这个运行进程从队列中移去。
缺点是平均等待时间往往很长。

护航效果(convoy effect):所有其他进程都等待一个大进程释放CPU。与让较短进程先进行相比,这会导致CPU和设备的使用率降低。

最短作业优先调度

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

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

SJF调度算法是最优的,因为它的平均等待时间最小。
但是SJF算法的真正困难是如何知道下次CPU执行的长度。这也导致了SJF调度经常用于长期调度,而不能在短期CPU调度级别上实现

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

一种办法就是试图近似SJF调度,如下次CPU执行通常预测为以前CPU执行的测量长度的指数平均(exponential average)
SJF调度可以是抢占的,也可以是非抢占的,抢占的SJF调度也被称为最短剩余时间优先(shortest-remaining-time-first)调度。听名字就很容易理解了。

优先级调度

优先级调度(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调度流程:

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

RR算法的性能很大程度上取决于时间片的大小。大多数现代操作系统的时间片为10~100ms,上下文切换的时间一般少于10ms,因此,上下文切换的时间仅占时间片的一小部分。

多级队列调度

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

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

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

1. 系统进程
2. 交互进程
3. 交互编辑进程
4. 批处理进程
5. 学生进程

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

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

线程调度

竞争范围

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

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

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

通常pcs采用优先级调度,用户等级线程的优先级是程序员设置的。

多处理器调度

多处理器调度的方法

非对称多处理器(asymmetric multiprocessing):

让一个处理器处理所有调度决定,I/O处理以及其他系统活动,其他的处理器只执行用户代码。
因为只有一个处理器访问系统数据结构,减少了数据共享的需要。

对称多处理器(Symmetric MultiProcessing, SMP):

即每个处理器自我调度。所有进程可能处于一个共同的就绪队列中,或每个处理器都有它自己的私有就绪进程队列。

处理器亲和性

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

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

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

第一个处理器的缓存设为无效,第二个处理器缓存应重新填充。并且缓存的无效或重新填充的代价高。

处理器亲和性(processor affinity):一个进程对它运行的处理器具有亲和性,大多数SMP系统试图避免将进程从一个处理器移到另一个处理器,而是试图将一个进程运行在同一个处理器上

软亲和性(soft affinity):一个操作系统试图保持进程运行在同一个处理器上(但不保证他会这么做)

硬亲和性(hard affinity):允许某个进程运行在某个处理器子集上。

多核处理器

传统上smp系统具有多个物理处理器,以便于多个线程并发执行,最近的做法:多个处理器放置在同一个物理芯片上,对操作系统而言他是一个独立的处理器

在双线程双核系统中,操作系统会有四个逻辑处理器

内存停顿(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。
调度程序可以根据进程的截止期限或速率要求来分配优先级。
posted @ 2021-01-24 21:02  陌天森  阅读(366)  评论(0)    收藏  举报