文章目录
- 一、中断与中断系统
- 1.1 什么是中断?
- 1.1.1 外中断(硬件)
- 1.1.2 异常(内中断)
- 1.2 中断机制的原理
- 1.2.1 中断装置
- 1、中断源与中断字
- 2、中断类型与中断向量
- 3、中断嵌套与系统栈
- 4、中断优先级别与中断屏蔽
- 1.2.2 中断处理逻辑
- 1.2.3 现场级别与保存位置
- 1.2.4 嵌套中断与系统栈
- 1.2.5 进程状态转换的分解图
- 1.2.6 中断处理例程
- 1.2.6.1 I/O中断 处理
- 1.2.6.2 时钟中断 处理
- 1.2.6.3 控制台中断处理
- 1.2.6.4 硬件故障中断处理
- 1.2.6.5 程序错误中断处理
- 1.2.6.6 自愿性中断处理
- 二、处理机调度
- 2.1 调度的基本概念
- 2.2 调度的三个层次
- 2.2.1 作业与高级调度
- 2.2.2 交换与中级调度
- 2.2.3 低级调度
- 2.3 进程调度的时机,切换与过程、方式
- 2.3.1 进程调度的时机——什么时候分配处理器?
- 2.3.2 如何分配处理器——进程调度方式
- 2.3.3 调度器和闲逛进程(scheduler)
- 2.4 按照什么原则分配处理器——进程调度算法
- 2.4.1 调度算法的评价指标
- 2.4.1.1 CPU利用率
- 2.4.1.2 系统吞吐量
- 2.4.1.3 周转时间
- 2.4.1.4 等待时间
- 2.4.1.5 响应时间
- 2.4.2 调度算法
- 2.4.2.1 先来先服务(FCFS,First Come First Serve)
- 2.4.2.2 最短作业优先(SJF,Shortest Job First )
- 2.4.2.3 最短剩余时间算法(SRTN,Shortest Remaining Time Next)
- 2.4.2.4 高响应比优先(HRRN,Highest Response Ratio Next)
- 2.4.2.5 时间片轮转调度算法(RR,Round-Robin)
- 2.4.2.6 优先级调度算法(highest priority number first)
- 2.4.2.7 多级反馈队列调度算法
- 2.4.2.8 多级队列调度算法(multilevel queue,MLQ)
- 2.5 实时调度
- 2.5.1 实时调度相关概念
- 2.5.2 实时调度调度算法
- 2.5.2.1 最早截止期优先调度算法(EDF)
- 2.5.2.2 速率单调调度(RMS)
- 2.6 多处理机调度
- 2.6.1 自调度
- 2.6.2 组调度
- 2.7 系统举例(待补充)
- 2.7.1 Linux进程调度
- 2.7.2 Windows2000/XP线程调度
- 2.7.3 UNIX进程调度
一、中断与中断系统
1.1 什么是中断?
在程序运行过程中出现某种紧急事件,必须中止当前正在运行的程序,转去处理此事件,然后再恢复原来运行的程序,这个过程称为中断。
中断可以分为两类:外中断和异常。
1.1.1 外中断(硬件)
外中断(Interruption),是指来自 CPU 执行指令外部的事件,通常用于信息输入/输出,如设备发出的 I/O 结束中断,表示设备输入/输出处理已经完成。时钟中断,表示一个固定的时间片已到,让处理机处理计时、启动定时运行的任务等。
1.1.2 异常(内中断)
异常(Exception)也称内中断,是指来自 CPU执行指令内部的事件,如程序的非法操作码、地址越界、运算溢出、虚存系统的缺页及专门的陷入指令等引起的事件。异常不能被屏蔽,一旦出现,就应立即处理。
1.2 中断机制的原理
1.2.1 中断装置
中断装置是中断系统中的硬件部分,它的职能是发现并响应中断,具体包括以下几个步骤:
- ①识别中断源。当有多个中断源同时存在时,由中断装置选择优先级别最高的中断源。
- ②保存现场。将正在运行的进程的程序状态字及指令寄存器中的内容压入系统栈。
- ③引出中断处理程序。将与中断事件相对应的中断向量由内存指定单元处取出并送入程序状态字及指令寄存器中,如此便转入对应的中断处理程序。
1、中断源与中断字
引起中断的事件称为中断源。例如,外围设备执行完输入输出操作、程序执行非法指令、用户在终端上输入一条命令等,这些都是可能引起处理器中断的事件,因而都是中断源。
中断寄存器保存的中断事件相关信息被称为中断字。中断装置发现并响应中断后,转到相应的中断处理程序。该程序在处理中断时通常需要进一步了解与中断事件相关的一些信息,例如对于设备中断,需要知道设备传输情况。为此,硬件系统为每一个中断源设置一个中断寄存器,当中断发生时,硬件系统将与中断相关的详细信息存入该寄存器中,以便中断处理程序从中进一步分析触发中断的原因并采取相应的处理措施。
2、中断类型与中断向量
除了前面由内部外部事件对中断进行分类,我们也可以将中断分为:强迫性中断和自愿性中断。
1、强迫性中断
这类中断事件是正在运行的程序所不期望的。强迫性中断事件是否发生,何时发生,事先无法预知,因而运行程序可能在任意位置被打断。这类中断大致有以下几种:
- 时钟中断:如固定的时间片已到
- I/O中断:如设备出错、传输结束
- 控制台中断:系统操作员通过控制台发出命令
- 硬件故障中断:如掉电、内存校验错误
- 程序错误中断:目态执行特权指令、地址越界、虚拟存储中缺页故障或缺段故障、溢出、除0操作等
2、自愿性中断
这类中断事件是正在运行的程序有意识安排的。通常由于正在运行的程序执行访管指令而引起自愿性中断事件,其目的是要求系统提供某种服务。这类中断的发生具有必然性,而且发生位置确定。
因为对同类事件的处理方法是相同的,所以不是每个中断源都有一个中断处理程序,而是每类中断事件有一个中断处理程序。
每个中断处理程序有一个入口地址(PC)及其运行环境(PSW),它们存放在内存中的固定单元处。当中断事件发生时,中断装置根据中断类别自动地将对应的PSW和PC送入程序状态字和指令计数器中,如此便转移到对应的中断处理程序。这种转移类似于向量转移,因而PSW和PC 被称为中断向量。
3、中断嵌套与系统栈
如果系统正在执行一个事件的中断操作,又响应了新的中断,我们称发生了中断嵌套。
理论上,中断嵌套层数是没有限制的。实际情况中,我们一般只允许相应更为紧迫的中断事件,也就是只允许优先级别更高的中断事件打断它,而硬件中断优先级通常是有限的。所以中断嵌套实际层数一般不会超过中断优先级别的个数。
对于嵌套中断来说,现场恢复的次序与现场保存的次序正好相反,故采用栈作为中断现场保存区域。因为操作系统需要访问这个栈,所以它应当被设在系统空间中,而且由于中断发生时,被中断程序的程序状态字和指令计数器的值是由硬件中断装置压入系统栈中的,因而系统栈区的位置实际上是由硬件确定的。
需要注意的是,系统栈内除PC以及PSW外还保存了其它现场信息,如通用寄存器的值等。而这些信息是由中断处理程序根据需要进行保存的。中断装置只保存了最基本的现场信息。
由于系统栈还可以传送操作系统子系统之间相互调用的参数、返回值以及返回地址,这一点与用户使用用户栈情形相仿。因此,我们可以把中断看成一种特殊的子程序调用,只不过其发生时刻具有不确定性。
4、中断优先级别与中断屏蔽
根据引起中断事件的重要性和紧迫程度,硬件将中断源分为若干优先级,称为中断优先级别。如果有多个中断同时发生,硬件系统将首先响应优先级别最高的中断请求。对于相同优先级别的中断,硬件系统将按照事先规定好的次序依次响应。
为了避免中断嵌套层数过多,硬件系统提供中断屏蔽指令,利用该指令可以暂时禁止中断源向处理器发送中断请求。当然,需要时,我们还可以利用硬件指令接触被屏蔽的中断源。
通常,在一个中断事件处理过程中,程序屏蔽包括该级别在内的所有低优先级别的中断,但是允许更高优先级别的中断中途插入。这样,嵌套中断事件优先级按照响应顺序递增。
中断优先级由硬件决定,一般不可改变,但程序可以适当调整中断事件相应次序。如,想要优先响应级别为5的中断事件,可以将优先级别高于5的中断源暂时屏蔽掉。
在操作系统的核心中通常有这样的程序段,它们的执行不允许任何中断事件打扰,此时会屏蔽所有的中断源,这类操作我们称之为关中断,处于关中断状态下执行的程序段应当尽量简短,否则可能会丢失信息,也会影响系统的并发性。
与关中断对应的是开中断,二者是我们实现原子操作的关键。
1.2.2 中断处理逻辑
- 中断装置响应中断请求,交换中断向量进入中断处理程序
- 关中断
- 保存现场信息
- 分析中断源
- 开放高优先级中断
- 中断处理
- 处理完:系统栈恢复现场,返回上层中断或目态
- 未处理完:重复
1.2.3 现场级别与保存位置
中断现场 VS 进程切换现场
中断现场:保存在系统栈
进程切换现场:保存在进程PCB
-
中断分析
- 何时等待/剥夺?——处于核心态,无嵌套中断或有嵌套中断
- 等待/剥夺几次?可能多次
- 保存在PCB的是什么级别的现场?核心级别
- 等待/剥夺时系统栈如何?栈底是目态现场,然后是嵌套函数的返回点,参数,局部变量,返回值;如有嵌套,接下来是核心现场,然后是嵌套函数的返回点、参数、局部变量、返回值(可能多重)
等待和剥夺都是由操作系统完成的,因而等待和剥夺发生在内核态,因而保存在PCB内的现场都是内核级别的现场,并非目态程序的现场。
1.2.4 嵌套中断与系统栈
目态程序运行时,其对应的系统栈是空的,发生中断时,栈底是目态现场(包括PSW、PC中断处理程序使用的寄存器),然后是中断处理程序的嵌套函数调用的返回点、参数、局部变量、返回值;
如果中断有嵌套,接下来是核心级别现场,然后是嵌套函数调用的返回点、参数、局部变量、返回值,嵌套可能是多重的。
1.2.5 进程状态转换的分解图
考虑系统状态与中断,可以给出更加完整的进程状态转换关系,目态运行的用户程序P发生中断时进入该进程的核心态,嵌套中断发生时仍处于该进程的核心态,嵌套中断返回时仍处于该进程的核心态,非嵌套中断返回时回到目态 P’。若P = P’则说明中断未导致进程切换,若P ≠ P’则说明发生了进程切换。
进程状态转换与操作系统动作之间的对应关系如下:
1.2.6 中断处理例程
1.2.6.1 I/O中断 处理
I/O中断一般由通道发出,可以分为如下两种情况:
- 输入输出操作正常结束
- 如果需要继续传输数据,那么准备好数据后启动通道
- 对于发出输入输出操作请求且正在等待数据传输完成的进程,将其唤醒
- 输入输出传输错误
- 如果是外部干扰因素引起,那么重复执行一两次就行
- 如果是设备故障,那么多少次也不行
- 所以通常以3次为上界,如果重复执行3次都不行,就通知系统操作员
1.2.6.2 时钟中断 处理
之前提到过,时钟可分为硬件时钟和软件时钟。
硬件时钟:分为绝对时钟和间隔时钟。前者不中断,后者每隔一段时间发出中断信号
软件时钟:利用硬件定时机构和程序来实现,也不发生中断。
当时钟中断触发时,中断处理程序要做许多与系统管理和维护有关的工作:
- 进程管理。
- 采用时间片轮转算法的系统中,记录进程已经占用处理机时间并判断时间片是否用完。
- 采用可抢占CPU动态优先数处理机调度算法的系统,重新计算各个进程优先数,并判断是否有高优先级的进程出现。
- 作业管理。
- 记录作业在输入井内的等待时间,以及当前的优先级别,以便作业调度程序据此决定下一个将要进入系统执行的作业。
- 资源管理
- 动态统计运行进程占有和使用处理机等资源的时间等。
- 事件处理
- 在实时系统中,定时向被控制对象发送控制信号等。
- 系统维护
- 定时运行死锁检测程序、定时运行系统记账程序等。
- 实现软件时钟
- 利用硬件间隔时钟和一个存储单元可以实现软件时钟。如程序每1000ms执行一次,而硬件间隔时钟是10ms一次中断,那么我们初始将对应内存单元timer置为100,每次时钟中断timer-1,当timer = 0,我们执行程序同时置timer为1000
1.2.6.3 控制台中断处理
系统操作员可以利用控制台向系统发出中断请求。当按下控制台上的某一个按键后,就会产生一个中断信号,该中断信号相当于一条操作命令,操作系统将转到相应的中断处理程序,其中断请求内容以及处理方法与具体系统有关。
1.2.6.4 硬件故障中断处理
硬件故障中断处理必须有人工干预,中断处理程序的工作是保存现场信息,向系统操作员报告故以便维护和修正。
- 电源故障处理
- 当发生电源故障时如掉电,硬件设备能够保证继续工作一段时间,操作系统可以利用这段时间做以下3项工作。
- 将寄存器内容和内存信息写至外存储器。
- 停止外围设备工作。
- 停止处理器工作。
- 当故障排除后,可进行系统恢复,主要工作如下。
- 启动处理器执行恢复程序。
- 启动外围设备工作。
- 将断电时保存到外存储器中的信息取回到对应的寄存器和内存中。
- 除了上述方案,更为理想的方案是预防,现在由于不间断电源(uninterruptible power supply,UPS)出现,已经成为可能。
- UPS同时具有蓄电和稳压的作用,当发生故障UPS可以继续供电足够长的时间。
- 当发生电源故障时如掉电,硬件设备能够保证继续工作一段时间,操作系统可以利用这段时间做以下3项工作。
- 主存故障处理
- 这是由于内存校验线路发现奇偶校验错误或海明校验错误而引起的中断。中断处理程序可以对错误单元进行检测并在确认错误后将其所在区域永久性地划分为不可用区域。
1.2.6.5 程序错误中断处理
如果一个中断事件只影响正在运行的进程自身,不影响其他进程和操作系统,则既可由操作系统处理,也可由用户自行处理
如果一个中断事件可能影响其他进程或操作系统,则只能由操作系统处理
- 只能由系统处理的中断
- 有内存访问地址越界、执行非法特权指令、缺页故障、缺段故障等。这类中断完全由操作系统统一处理。如果中断是由于程序错误而引起的,通常向系统操作员汇报出错的进程号、出错位置和错误性质等,并要求系统操作员干预;如果中断是由于缺页故障或缺段故障而引起的,则要将所需页或段动态地调入内存。
- 可以由用户处理的中断
- 可以由用户处理的中断有浮点数溢出、阶码下溢、除数为0等。不同的用户对这类错误可能有不同的处理方法,因而可以由各个用户自行处理。如果用户程序没有提供特定的处理程序,将由操作系统按照标准处理方法加以处理。
1.2.6.6 自愿性中断处理
这类中断是由于用户程序在目态执行访管指令而引起的,其目的是要求系统为其提供某种服务。访管指令由指令码和访管中断号组成,即
SVC n
**SVC(supervisor call)**是指令码,即访管指令,n为访管中断号,是一个整数,表示要访问要求的类型。
硬件中断装置将访管中断号n送入旧的程序状态字内的中断码字段,访管中断总控程序从系统栈中将其取出,并据此转入对应的服务程序。
使用访管指令一般形式如下:
准备参数
SVC n
取返回值
访管指令的执行将触发自愿性中断,由中断向量引导进入系统调用总控程序。该程序由旧的程序状态字中取出中断码",然后根据n的值转到对应的服务程序。为了方便转移的实现,系统中通常设有一个系统调用驱动表,根据访管中断号查找此表便可找到对应系统调用命令处理程序的入口。
二、处理机调度
2.1 调度的基本概念
生活中有如下场景,在银行,经常看到前台有普通排起长龙,而也有VIP客户可以被优先服务或者专属客服。
早上和室友争夺马桶的宝座,和室友商定谁快谁先来……
当有一堆任务要处理,但由于资源有限,这些事情没法同时处理。这就需要确定某种规则来决定处理这些任务的顺序,这就是**“调度”**研究的问题。
2.2 调度的三个层次
2.2.1 作业与高级调度
高级调度(high-level scheduling)又称作业调度(job scheduling)或长程调度(long-term scheduling,或称长期调度),其职能是将一个作业由输入井调入内存,并为其建立相应的PCB,使其具有运行的资格,调出时撤销PCB。
2.2.2 交换与中级调度
进程在内存和外存储器之间的调度称为交换(swapping)。目标有两个:一是缓解内存空间等资源紧张的矛盾。二是减小并发度以降低系统开销。(后面存储器一章会细嗦
中级调度(middle-level scheduling)也称为中程调度(medium-term scheduling,或称中期调度),是系统控制并发程度的一个调度级别。
当系统并发度过高时,内存不够时,可将某些进程的数据调出外存,待以后系统并发度较低时再调回内存。当然,**进程在内存和外存储器之间的调度也需要依据某种调度原则,即调度算法。**一般依据系统的设计目标确定。
一个进程可能会被多次调出、调入内存,因此中级调度发生的频率要比高级调度更高。
暂时调到外存等待的进程状态为挂起状态(挂起态,suspend),挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态
注意挂起和阻塞的区别
两种状态都是暂时不能获得CPU的服务,但挂起态是将进程映像调到外存去了,而阻塞态下进程映像还在内存中。
有的操作系统会把就绪挂起、阻塞挂起分为两个挂起队列,甚至会根据阻塞原因不同再把阻塞挂起进程进一步细分为多个队列。
2.2.3 低级调度
低级调度(low-level scheduling)或短程调度(short-term scheduling,或称短期调度),按照某种策略从就绪队列中选取一个进程或线程,将处理机分配给它,使其真正向前推进。
要做什么 | 调度发生在… | 发生频率 | 对进程状态的影响 | |
---|---|---|---|---|
高级调度(作业调度) | 按照某种规则,从后备队列中选择合适的作业将其调入内存,并为其创建进程 | 外存→内存(面向作业) | 最低 | 无->创建态->就绪态 |
中级调度(内存调度) | 按照某种规则,从挂起队列中选择合适的进程将其数据调回内存 | 外存->内存(面向进程) | 中等 | 挂起态->就绪态(阻塞挂起->阻塞态) |
低级调度(进程调度) | 按照某种规则,从就绪队列中选择一个进程为其分配处理机 | 内存->CPU | 最高 | 就绪态->运行态 |
2.3 进程调度的时机,切换与过程、方式
进程调度(低级调度),就是按照某种算法从就绪队列中选择一个进程为其分配处理机。
什么时候分配处理器——进程调度时机
如何分配处理器——进程调度方式
按照什么原则分配处理器——进程调度算法
2.3.1 进程调度的时机——什么时候分配处理器?
需要进程调度的与切换的情况:
- 当前运行的进程主动放弃处理机 : )
- 进程正常终止
- 运行过程中发生异常而终止
- 进程主动请求阻塞(如等待I/O)
- 当前运行的进程被动放弃处理机 x_x
- 分给进程的时间片用完
- 有更紧急的事要处理(如I/O中断)
- 有更高优先级的进程进入就绪队列
不能进程调度的与切换的情况:
- 在处理中断的过程中。中断处理过程复杂,与硬件密切相关,很难做到在中断处理过程中进行进程切换。实际上,中断过程中是否可以进行进程切换不能给出统一回答
- 进程在操作系统内核程序临界区中。
- 内核程序临界区 VS 临界区,二者不同
- 内核程序临界区一般是用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的PCB组成)
- 临界区:访问临界资源的代码。临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。(后面互斥同步部分的内容)
- 在原子操作过程中(原语)。原子操作不可中断,要一气呵成(如修改PCB中进程状态标志,并把PCB放到相应队列)
2.3.2 如何分配处理器——进程调度方式
进程调度方式可分为两种:
非剥夺调度方式,又称非抢占方式。即,只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止或主动进入阻塞态。
特点:实现简单,系统开销小但是无法及时处理紧急任务,适合于早期的批处理系统
剥夺调度方式,又称抢占方式。当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要紧迫的那个进程。
特点:可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能(通过时钟中断)。适合于分时操作系统、实时操作系统
“狭义的进程调度”与“进程切换”的区别:
狭义的进程调度指的是从就绪队列中选中一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程也可能是另一个进程,后一种情况就需要进程切换)
进程切换是指一个进程让出处理机,由另一个进程占用处理机的过程。
广义的进程调度包含了选择一个进程和进程切换两个步骤。
进程切换的过程主要如下:
- dispatcher(关中断状态下,汇编语言完成)
- 保存下降进程的现场
- 寄存器(PSW,PC,SP,通用寄存器,地址寄存器)→PCB
- 选择上升进程
- 按处理机调度算法(处理机调度程序)
- 恢复上升进程的现场
- PCB→寄存器
- 先恢复通用寄存器、地址寄存器和 SP,最后恢复PSW,PC
- PSW和PC必须用一条指令恢复
- PCB→寄存器
- 保存下降进程的现场
注意:进程切换是有代价的,因此如果过于频繁的进行进程调度、切换,必然会使整个系统的效率降低,使系统大部分时间都花在了进程切换上,而真正用于执行进程的时间减少。
这也是为什么我们要选取合适的进程调度算法。
2.3.3 调度器和闲逛进程(scheduler)
②、③由调度程序引起,调度程序决定:
让谁运行?——调度算法
运行多久?——时间片大小
调度时机——什么事件会触发”调度程序“?
- 创建新进程
- 进程退出
- 运行进程阻塞
- I/O中断发生(可能唤醒某些阻塞进程)
非抢占式调度策略,只有运行进程阻塞或退出才触发调度程序工作
抢占式调度策略,每个时钟中断或k个时钟中断会触发调度程序工作
不支持内核级线程的操作系统,调度程序的处理对象是进程
支持内核级线程的操作系统,调度程序的处理对象是内核线程
闲逛进程
调度程序永远的备胎,没有其他就绪进程时,运行闲逛进程(idle)
闲逛进程的特性:
- 优先级最低
- 可以是0地址指令,占一个完整的指令周期(指令周期末尾例行检查中断)
- 能耗低
我们打开任务管理器的详细信息可以看到PID为0的闲逛进程。
2.4 按照什么原则分配处理器——进程调度算法
2.4.1 调度算法的评价指标
2.4.1.1 CPU利用率
**CPU利用率:**指CPU“忙碌”的时间占总时间的比例。
利用率 = 忙碌的时间 总时间 利用率=\frac{忙碌的时间}{总时间} 利用率=总时间忙碌的时间
Eg:Eg:某计算机只支持单道程序,某个作业刚开始需要在CPU上运行5秒,再用打印机打印输出5秒,之后再执行5秒,才能结束。在此过程中,CPU利用率、打印机利用率分别是多少?
C P U 利用率 = 5 + 5 5 + 5 + 5 = 66.66 % 打印机利用率 = 5 5 + 5 + 5 = 33.33 % CPU利用率=\frac{5+5}{5+5+5}=66.66\% \\ 打印机利用率= \frac{5}{5+5+5}=33.33\% CPU利用率=5+5+55+5=66.66%打印机利用率=5+5+55=33.33%
在考虑程序并发执行情况时,可以利用甘特图来辅助计算。
2.4.1.2 系统吞吐量
**系统吞吐量:**单位时间内完成作业的数量。
系统吞吐量 = 总共完成了多少道作业 总共花了多少时间 系统吞吐量=\frac{总共完成了多少道作业}{总共花了多少时间} 系统吞吐量=总共花了多少时间总共完成了多少道作业
Eg:某计算机系统处理完10道作业,共花费100秒,则系统吞吐量为?
10 / 100 = 0.1道
2.4.1.3 周转时间
周转时间:从作业被提交给系统开始,到作业完成为止的这段时间间隔。
它包括四个部分:
-
作业在外存后备队列上等待作业调度(高级调度)的时间
-
进程在就绪队列上等待进程调度(低级调度)的时间
-
进程在CPU上执行的时间
-
进程等待I/0操作完成的时间。
后三项在一个作业的整个处理过程中,可能发生多次。
( 作业 ) 周转时间 = 作业完成时间 − 作业提交时间 平均周转时间 = 各作业周转时间之和 作业数 (作业)周转时间=作业完成时间-作业提交时间\\ 平均周转时间=\frac{各作业周转时间之和}{作业数} (作业)周转时间=作业完成时间−作业提交时间平均周转时间=作业数各作业周转时间之和
而有的作业运行时间短,有的作业运行时间长,因此在周转时间相同的情况下,运行时间不同的作业,给用户的感觉肯定是不一样的
因此,还有另一种指标——带权周转时间
带权周转时间 = 作业周转时间 作业实际运行的时间 = 作业完成时间 − 作业提交时间 作业实际运行的时间 平均带权周转时间 = 各作业带权周转时间之和 作业数 带权周转时间=\frac{作业周转时间}{作业实际运行的时间}=\frac{作业完成时间-作业提交时间}{作业实际运行的时间} \\ 平均带权周转时间=\frac{各作业带权周转时间之和}{作业数} 带权周转时间=作业实际运行的时间作业周转时间=作业实际运行的时间作业完成时间−作业提交时间平均带权周转时间=作业数各作业带权周转时间之和
- 带权周转时间必然 ≥ 1
- 带权周转时间与周转时间都是越小越好
2.4.1.4 等待时间
计算机的用户希望自己的作业尽可能少的等待处理机
等待时间,指进程/作业处于等待处理机状态时间之和,等待时间越长,用户满意度越低。
对于进程来说,等待时间就是指进程建立后等待被服务的时间之和,在等待I/O完成的期间其实进程也是在被服务的,所以不计入等待时间。
对于作业来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间。
一个作业总共需要被CPU服务多久,被IO设备服务多久一般是确定不变的,因此调度算法其实只会影响作业/进程的等待时间。当然,与前面指标类似,也有**“平均等待时间”**来评价整体性能。
2.4.1.5 响应时间
对于计算机用户来说,会希望自己的提交的请求(比如通过键盘输入了一个调试命令)尽早地开始被系统服务、回应。
**响应时间:**从用户提交请求到首次产生响应所用的时间。
2.4.2 调度算法
2.4.2.1 先来先服务(FCFS,First Come First Serve)
算法思想 | 主要从“公平"的角度考虑 |
算法规则 | 按照 [作业/进程] 到达的先后顺序进行服务 |
用于作业/进程调度 | 用于作业调度时,考虑的是哪个作业先到达后备队列;用于进程调度时,考虑的是哪个进程先到达就绪队列 |
是否可抢占? | 非抢占式 |
优缺点 | 优点:公平,实现简单;缺点:排在长作业(进程)后面的短作业需要等待很长时间,带权周转时间很大,对短作业来说用户体验不好。即,FCFS算法对长作业有利,对短作业不利 |
是否会导致饥饿 | 不会 |
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用先来先服务调度算法,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0 | 7 |
P2 | 2 | 4 |
P3 | 4 | 1 |
P4 | 5 | 4 |
调度顺序为: P1 -> P2 -> P3 -> P4
P1 | P2 | P3 | P4 | |
---|---|---|---|---|
等待时间 | 0 | 5 | 7 | 7 |
周转时间 | 7 | 9 | 8 | 11 |
带权周转时间 | 1 | 9/4 | 8 | 11/4 |
平均等待时间:(0 + 5 + 7 + 7) / 4
平均周转时间:(7 + 9 + 8 +11) / 4
平均带权周转时间:(1 + 9/4 + 8 + 11/4) / 4
2.4.2.2 最短作业优先(SJF,Shortest Job First )
算法思想 | 追求最少的平均等待时间,最少的平均周转时间、最少的平均平均带权周转时间 |
算法规则 | 最短的 [作业/进程] 优先得到服务(所谓“最短”,是指要求服务时间最短) |
用于作业/进程调度 | 既可用于作业调度,也可用于进程调度。用于进程调度时称为“短进程优先(SPF,Shortest Process First)算法 |
是否可抢占? | 非抢占式,后面有一个用来对比的,可抢占式——最短剩余时间算法(SRTN,Shortest Remaining Time Next) |
优缺点 | 优点:最短的”平均等待时间、平均周转时间 缺点:不公平。对短作业有利,对长作业不利。可能产生饥饿现象。另外,[作业/进程] 的运行时间是由用户提供的,并不一定真实,不一定能做到真正的短作业优先。 |
是否会导致饥饿 | 会。如果源源不断地[有短作业/进程]到来,可能使[长作业/进程]长时间得不到服务,产生**“饥饿”现象。如果一直得不到服务,则称为“饿死"** |
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用最短作业优先调度算法,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0 | 7 |
P2 | 2 | 4 |
P3 | 4 | 1 |
P4 | 5 | 4 |
调度顺序为: P1 -> P3 -> P2 -> P4
P1 | P2 | P3 | P4 | |
---|---|---|---|---|
等待时间 | 0 | 6 | 3 | 7 |
周转时间 | 7 | 10 | 4 | 11 |
带权周转时间 | 1 | 2.5 | 4 | 11/4 |
平均等待时间:(0 + 6 + 3 + 7) / 4
平均周转时间:(7 + 10 + 4 +11) / 4
平均带权周转时间:(1 + 2.5 + 4 + 11/4) / 4
2.4.2.3 最短剩余时间算法(SRTN,Shortest Remaining Time Next)
即抢占式的最短作业优先算法。
我们看当可抢占时,对于前面问题的执行情况是怎样的。
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用最短剩余时间算法调度算法,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0 | 7 |
P2 | 2 | 4 |
P3 | 4 | 1 |
P4 | 5 | 4 |
调度顺序为: P1 -> P2 -> P3 -> P2 -> P4 -> P1
P1 | P2 | P3 | P4 | |
---|---|---|---|---|
等待时间 | 9 | 1 | 0 | 2 |
周转时间 | 16 | 5 | 1 | 6 |
带权周转时间 | 16/7 | 5/4 | 1 | 6/4 |
平均等待时间:(9 + 1 + 0 + 2) / 4
平均周转时间:(16 + 5 + 1 +6) / 4
平均带权周转时间:(16/7 + 5/4 + 1 + 6/4) / 4
细节:
- 题目未特别说明,所提到的“短[作业/进程]优先算法”默认非抢占
- 很多资料上讲“SJF算法的平均等待时间、平均周转时间最短”,然而上面的例子中SRTN算法更短。实际上,只有当所有进程几乎同时到达或所有进程同时可运行时,我们才可以说SJF算法的平均等待时间、平均周转时间最短
- 虽然严格来说,SJF的平均等待时间、平均周转时间并不一定最少,但相比于其他算法(如FCFS)SIF依然可以获得较少的平均等待时间、平均周转时间
- 如果选择题中遇到“SJF 算法的平均等待时间、平均周转时间最少”的选项,那最好判断其他选项是不是有很明显的错误,如果没有更合适的选项,那也应该选择该选项
思考:
- FCFS算法在每次调度时,选择一个当前等待时间最长的[进程/作业]为其服务,没有考虑到作业的运行时间,对短作业不友好,其“公平”有失偏颇
- SJF 算法是选择一个执行时间最短的作业为其服务。但是又完全不考虑各个作业的等待时间,因此导致了对长作业不友好的问题,甚至还会造成饥饿问题
- emmmm,有没有即考虑到各个作业的等待时间,又能兼顾运行时间的算法捏?
2.4.2.4 高响应比优先(HRRN,Highest Response Ratio Next)
响应比 = 等待时间 + 要求服务时间 要求服务时间 显然,响应比 ≥ 1 响应比=\frac{等待时间+要求服务时间}{要求服务时间} \\ 显然,响应比 \ge 1 响应比=要求服务时间等待时间+要求服务时间显然,响应比≥1
算法思想 | 要综合考虑 [作业/进程] 的等待时间和要求服务的时间 |
算法规则 | 每次调度时,先计算各个[作业/进程]的响应比,选择响应比最高的[进程/作业]为其服务 |
用于作业/进程调度 | 既可用于作业调度,也可用于进程调度。 |
是否可抢占? | 非抢占式,因而只有当前运行的[进程/作业]主动放弃处理机,才需要调度,才需要计算响应比。 |
优缺点 | 综合考虑了等待时间和运行时间(要求服务时间) 等待时间相同时,要求服务时间最短的优先(SLF的优点) 要求服务时间相同时,等待时间长的优先(FCFS的优点) 对于长作业来说,随着等待时间越来越久,其响应比也会越来越大,从而避免了长作业饥饿的问题 |
是否会导致饥饿 | 不会哦 |
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用高响应比优先调度算法,计算各进程的等待时间、平均等待时间、周转时间、平均周转时间、带权周转时间、平均带权周转时间。
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0 | 7 |
P2 | 2 | 4 |
P3 | 4 | 1 |
P4 | 5 | 4 |
算法流程:
- 0时刻:只有P1抵达就绪队列,P1上处理机
- 7时刻:P1下处理机,就绪队列中 Ratio[P2] = (5 + 4) / 4,Ratio[P3] = (3 + 1) / 1,Ratio[P4] = (2 + 4) / 4,所以P3上处理机
- 8时刻:P3下处理机,就绪队列中 Ratio[P2] = (6 + 4) / 4,Ratio[P3] = (3 + 4) / 4,所以P2上处理机
- 12时刻:P2下处理机,就绪队列只剩下P4,P4上处理机
- 16时刻:结束~
调度顺序为: P1 -> P3 -> P2 -> P4
P1 | P2 | P3 | P4 | |
---|---|---|---|---|
等待时间 | 0 | 6 | 3 | 7 |
周转时间 | 7 | 10 | 4 | 11 |
带权周转时间 | 1 | 2.5 | 4 | 11/4 |
平均等待时间:(0 + 6 + 3 + 7) / 4
平均周转时间:(7 + 10 + 4 +11) / 4
平均带权周转时间:(1 + 2.5 + 4 + 11/4) / 4
2.4.2.5 时间片轮转调度算法(RR,Round-Robin)
算法思想 | 公平地、轮流地为各个进程服务,让每个进程在一定时间间隔内都可以得到响应 |
算法规则 | 按照各进程到达就绪队列的顺序,轮流让各个进程执行个**时间片(**如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队。 |
用于作业/进程调度 | 用于进程调度(只有作业放入内存建立了相应的进程后,才能被分配处理机时间片) |
是否可抢占? | 抢占式。若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间片轮转调度算法属于抢占式的算法。由时钟装置发出时钟中断来通知CPU时间片已到 |
优缺点 | 优点:公平;响应快,适用于分时操作系统; 缺点:由于高频率的进程切换,因此有一定开销;不区分任务的紧急程度。 |
是否会导致饥饿 | 不会 |
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用时间片轮转调度调度算法,分析时间片大小分别是2、5时的进程运行情况
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0 | 5 |
P2 | 2 | 4 |
P3 | 4 | 1 |
P4 | 5 | 6 |
时间片大小为2时执行情况如下:
时间片大小为5时执行情况如下:
我们发现如果时间片太大,使得每个进程都可以在一个时间片内就完成,则时间片轮转调度算法退化为先来先服务调度算法,并且会增大进程响应时间。因此时间片不能太大。
如果时间片太小,会导致频繁进行调度和切换,增加系统的开销
因而 时间片轮转调度算法在实现时又分为两种情形:
- 基本轮转
- 对于基本轮转来说,分给所有进程的时间片的长度是相同的,而且是不变的。若不考虑数据传输等待,系统中的所有进程以基本上均等的速度向前推进。
- 改进轮转
- 对于改进轮转来说,分给不同进程的时间片的长度是不同的,而且(或者)是可变的。此时,系统可以根据不同进程的不同特性为其动态地分配不同长度的时间片,以便达到更灵活的调度效果。
2.4.2.6 优先级调度算法(highest priority number first)
算法思想 | 随着计算机的发展,特别是实时操作系统的出现,越来越多的应用场景需要根据任务的紧急程度来决定处理顺序 |
算法规则 | 调度时选择优先级最高的 [作业/进程] |
用于作业/进程调度 | 既可用于作业调度,也可用于进程调度。甚至,还会用于在之后会学习的I/O调度中 |
是否可抢占? | 抢占式、非抢占式都有。做题时的区别在于:非抢占式只需在进程主动放弃处理机时进行调度即可,而抢占式还需在就绪队列变化时,检查是否会发生抢占。 |
优缺点 | 优点:用优先级区分紧急程度、重要程度,适用于实时操作系统。可灵活地调整对各种作业/进程的偏好程度。 缺点:若源源不断地有高优先级进程到来,则可能导致饥饿 |
是否会导致饥饿 | 会 |
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用抢占式的优先级调度算法调度算法,分析进程运行情况(优先数越大,优先级越高)
进程 | 到达时间 | 运行时间 | 优先数 |
---|---|---|---|
P1 | 0 | 7 | 1 |
P2 | 2 | 4 | 2 |
P3 | 4 | 1 | 3 |
P4 | 5 | 4 | 2 |
运行情况如下:
上面的例子还是很好理解的,但是对于优先级调度算法,我们实际上还有两个问题要阐明一下:一是关于优先级的确定,二是就绪队列的组织。
实际上,就绪队列未必只有一个,我们可以按照不同优先级进行组织。另外,也可以把优先级高的进程排在更靠近队头的位置。
根据优先级是否可以动态改变,可将优先级分为静态优先级和动态优先级两种。
静态优先级:创建进程时确定,之后一直不变。
动态优先级:创建进程时有一个初始值,之后会根据情况动态地调整优先级。
如何合理地设置各类进程的优先级?
通常情况下:
- **系统进程优先级 高于用户进程 **
- 前台进程优先级 高于后台进程
- 操作系统更偏好 I/O型进程(或称 I/O繁忙型进程)(与I/O型进程相对的是计算型进程(或称CPU繁忙型进程))
- I/O设备和CPU可以并行工作。如果优先让I/O繁忙型进程优先运行的话,则越有可能让I/O设备尽早地投入工作,则资源利用率、系统吞吐量都会得到提升
如果采用的是动态优先级,什么时候应该调整?
可以从追求公平、提升资源利用率等角度考虑:
- 如果某进程在就绪队列中等待了很长时间,则可以适当提升其优先级。
- 如果某进程占用处理机运行了很长时间,则可适当降低其优先级
思考:
- FCFS的优点是公平
- SJF 算法的优点是能尽快处理完短作业,平均等待/周转时间等参数很优秀
- 时间片轮转调度算法可以让各个进程得到及时的响应
- 优先级调度算法可以灵活地调整各种进程被服务的机会
- 能否对其他算法做个折中权衡?得到一个
究极缝合怪综合表现优秀平衡的算法呢?
有!多级反馈队列调度算法。
2.4.2.7 多级反馈队列调度算法
算法思想 | 对其他调度算法的折中权衡 |
算法规则 | 1.设置多级就绪队列,各级队列优先级从高到低,时间片从小到大 2.新进程到达时先进入第1级队列,按FCFS原则排队等待被分配时间片,若用完时间片进程还未结束,则进程进入下一级队列队尾。如果此时已经是在最下级的队列,则重新放回该队列队尾 3.只有第k级队列为空时,才会为k+1级队头的进程分配时间片 |
用于作业/进程调度 | 用于进程调度 |
是否可抢占? | 抢占式的算法。在k级队列的进程运行过程中,若更上级的队列(1 ~ k - 1级)中进入了一个新进程,则由于新进程处于优先级更高的队列中,因此新进程会抢占处理机,原来运行的进程放回k级队列队尾。 |
优缺点 | 对各类型进程相对公平(FCFS的优点); 每个新到达的进程都可以很快就得到响应(RR的优点); 短进程只用较少的时间就可完成(SJF的优点); 不必实现估计进程的运行时间(避免用户作假); 可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、I/O密集型进程(拓展:可以将因I/O而阻塞的进程重新放回原队列,这I/O型进程就可以保持较高优先级) |
是否会导致饥饿 | 会(源源不断的短进程) |
例:各进程到达就绪队列的时间、需要的运行时间如下表所示。使用多级反馈队列调度算法,分析进程运行的过程。
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0 | 8 |
P2 | 1 | 4 |
P3 | 5 | 1 |
假设第1级、第2级、第3级队列优先级依次递减,时间片分别为1、2、4
那么有运行流程:P1(1) -> P2(1) -> P1(2) -> P2(1) -> P3(1) -> P2(2) -> P1(4) -> P1(1)
2.4.2.8 多级队列调度算法(multilevel queue,MLQ)
**多级队列调度算法(multilevel queue,MLQ)**按照进程类型设置多个就绪进程队列,进程创建成功后插入某个队列。
队列之间可采取固定优先级,或时间片划分
- 固定优先级:高优先级空时低优先级进程才能被调度
- 时间片划分:如三个队列分配时间50%、40%、10%
各队列可采用不同的调度策略,如:系统进程队列采用优先级调度、交互式队列采用RR、批处理队列采用FCFS
2.5 实时调度
2.5.1 实时调度相关概念
在实时系统中,时间起着至关重要的作用,即对每一个实时任务,都有一个时间约束要求,如在何时必须开始处理、在何时必须处理完毕等。在一个实时应用系统中可能有多个实时任务,每个实时任务都有其时间约束,实时调度(real-time-scheduling)的目标就是合理地安排这些任务的执行次序,使之满足各个实时任务的时间约束条件。
满足实时任务各自时间约束条件的调度称为实时调度。
按其发生规律可分为:
- 随机性实时任务:由随机事件触发,其发生时刻不确定
- 周期性实时任务:每隔固定时间发生一次
按照时间约束强弱又可分为:
- 硬实时(hard real - time):必须满足任务截止期要求,否则产生严重后果,硬实施系统不多
- 软实时(soft real - time):期望满足截止期要求
与实时调度相关的概念:
- **就绪时间(readytime):**实时任务产生并可以开始处理的时间
- **开始截止期(starting deadline):**实时任务最迟开始处理的时间,
- **处理时间(processingtime):**实时任务处理所需要的处理器时间
- **完成截止期(completion deadline):**实时任务最迟完成时间
- **发生周期(occurring period):**发生周期性实时任务的间隔时间
- 实时任务的紧迫程度通常用优先级表示
对于周期性实时任务来说,令G为任务P的处理时间,为任务的发生周期,则任务P1……Pn的可调度的必要条件为:
∑ i = 1 n C i T i ≤ 1 \sum_{i=1}^{n} \frac{C_{i}}{T_{i}} \le 1 i=1∑nTiCi≤1
比如现有周期性实时事务:
进程 | 就绪时间 | 处理时间 | 完成截止期 | 发生周期 |
---|---|---|---|---|
A | 0 | 10 | 20 | 20 |
B | 0 | 25 | 50 | 50 |
有10 / 20 + 25 + 50 = 1,可调度
2.5.2 实时调度调度算法
2.5.2.1 最早截止期优先调度算法(EDF)
最早截止期优先(earliest deadine first,EDF)调度优先选择完成截止期最早的实时任务。它是可剥夺式的。
对于新到达的实时任务,如果其完成截止期先于正在运行任务的完成截止期,则重新分派处理器,即剥夺。可以证明,对于最早截止期优先调度算法来说,可调度充分条件:
∑ i = 1 n C i T i ≤ 1 \sum_{i=1}^{n} \frac{C_{i}}{T_{i}} \le 1 i=1∑nTiCi≤1
例:进程A、B信息如下
进程 | 就绪时间 | 处理时间 | 完成截止期 | 发生周期 |
---|---|---|---|---|
A | 0 | 10 | 20 | 20 |
B | 0 | 25 | 50 | 50 |
我们尝试画出A、B并发执行下的执行情况:
2.5.2.2 速率单调调度(RMS)
单调速率调度(rate - monotonic scheduling,RMS)于1973年由Liu 和 Layland 提出,面向周期性实时任务,属于非剥夺式调度的范畴。速率单调调度将任务的周期作为调度参数,其发生频度越高,则调度级别越高。Lin和Layland已经证明,速率单调调度算法可调度的条件如下:
∑ i = 1 n C i T i ≤ n ( 2 1 n − 1 ) \sum_{i=1}^{n}\frac{C_{i}}{T_{i}} \le n(2^{\frac{1}{n}} - 1) i=1∑nTiCi≤n(2n1−1)
RMS上限值如下:
显然RMS的可调度条件比EDF更强,不过RMS调度实现比EDF简单,因为是非剥夺式的。
例:进程A、B、C信息如下:
进程 | Ti | Ci |
---|---|---|
A | 100 | 20 |
B | 150 | 40 |
C | 350 | 100 |
C 1 T 1 + C 2 T 2 + C 3 T 3 = 0.779 \frac{C1}{T1} + \frac{C2}{T2} + \frac{C3}{T3} = 0.779 T1C1+T2C2+T3C3=0.779
可调度,具体为:
2.6 多处理机调度
这里只考虑**对称式共享存储器多处理机(Symmetric shared-memory Multi Processor,SMP)**的调度。
2.6.1 自调度
问题:有的处理机就绪队列长,有的处理机就绪队列短
所以自调度(Self scheduling)选择只使用一个就绪队列,所有处理机从同一个就绪队列中取进程,这种方式也被称为均衡调度(balanced scheduling)
一个就绪队列(多处理机访问互斥)
- 优点
- 不需要专门的处理机从事任务分派工作,谁空闲谁就拿
- 任务分配均衡
- 缺点
- 当 CPU较多时,就绪队列成为瓶颈
- 线程两次调度可能处于不同处理机,这导致上一个的数据处理机在上一个处理机的Cache中
- 不能保证同组线程同时调度
例子:
- Mach,(是改进的自调度)
- 全局队列:系统一个
- 局部队列:每个CPU一个
- 调度时
- 首先考虑局部队列
- 然后考虑全局队列
2.6.2 组调度
**组调度(gang scheduling)**选择将一组相关(合作)的线程同时分派到多个处理机上运行。
优点:
- 避免合作线程之间的相互等待
- 降低开销,提高运行效率
例子:
- Cm*
- "Task force(一组相关的计算)