操作系统: 第三章节 :中断和处理机调度
一:中断与中断系统
-1:中断的概念:
在程序运行过程中出现某紧急事件,必须中止当前正在运行的程序,转去处理这个事件,然后再恢复原来运行的程序,这一过程称为中断.
-2:中断装置(硬件):
发现并相应中断的硬件结构:
工作:
-----识别中断源,如果多个中断源,按照急迫程度排队,
-----保存现场:PSW和PC压入系统栈
------引出中断处理程序:将中断向量对应的PSW和PC送入寄存器
正在运行某个程序时,发生中断(1),
先将当前程序的PSW和PC送入系统栈(2),
然后把中断向量的PSW和PC送往寄存器(3),
处理中断的目标程序(4),
处理完之后将原来的PSW和PC调回寄存器(5),
继续处理原来的程序(6).
-3:中断源和中断字:
中断源:引起中断的事件
中断寄存器:保存与中断事件相关信息的寄存器
中断字:中断寄存器的内容 :比如IO中断:设备状态寄存器的内容:忙or闲,IO结束or出错,复执次数;时钟中断没有中断字
-4:中断性质:
----强迫性中断:
时钟中断,IO设备中断,鼠标,键盘中断
硬件故障中断:power failure /内存校验出错
程序性中断:越界,越权,缺页,缺段,溢出,除0,非法指令
----自愿性中断:
系统调用:fd=open(fname,mode) //打开文件
访管指令:准备参数,svc n,取返回值
-5:中断类型和中断向量
-中断向量:中断处理程序的运行环境(PSW)和入口地址PC
每一类的中断事件都有一个中断向量.
他的存放位置是由硬件决定的,
中断向量的内容是OS在初始化的时候就确定了的.
-中断向量表:(硬件规定的)(入口的长度也是规定的左边的数字,哪一个入口对应哪一个中断类型也是硬件规定的)
PC1....是中断处理程序
-6中断嵌套:
系统处理一个中断的时候又相应了一个新的中断,称系统发生了中断嵌套
----一般原则:
只允许响应更紧迫的中断事件,中断嵌套的层数也有限制
实现方法:处理响应的中断时,需要去屏蔽掉<=该优先级的中断源
----系统栈:
在系统空间,由硬件决定位置,用来保存中断的现场信息:
对于嵌套中断,现场恢复的次序和保存的次序相反,因此使用stack
(
这里的stack不只是保存了PSW和PC,还保存了当时的一些现场信息:通用寄存器,标志寄存器等等
系统栈还传递操作系统子程序之间相互调用的参数,返回值和返回地址
)
中断相当于特殊的子程序调用,但是发生的时间不确定
(注意下面的状态第一个是目态,后面的中断处理都在管态)
--:-一些注意项:
-----由于进一步保存现场信息是通过运行中断处理程序完成,程序运行时可以进行中断嵌套,为保证正确操作系统不允许在保存现场信息时响应中断
-----恢复现场信息也是由中断处理程序来完成,此时的工作也不允许响应中断
(开头和结果对现场信息进行处理的时候要保证原子性)
也可以进行关中断:尽管产生了中断源且发出了中断请求,但CPU内部的PSW中的中断允许位被清除,此时不允许CPU响应任何中断,此现象为关中断。
完整的过程:
中断响应:
关中断:
保存现场
开中断
..
中断处理
...
关中断
恢复现场
开中断
中断返回
(微机系统第2章没有引入嵌套)
--中断优先级:根据引起中断的事件的重要性和紧迫程度,硬件将中断源分成若干个级别
--中断屏蔽:暂时禁止一个或多个中断源向处理机发出中断请求,屏蔽所有中断源就是关中断
中断屏蔽指令也是硬件系统提供的,通过他可以开or关中断
-7:中断处理程序(软件):
(等待or剥夺可能一次进程中发生多次)
中断分析,关于等待
何时等待? 处于核心态,无嵌套中断或有嵌套
等待几次? 可能多次
保存在PCB的是什么级别现场? 核心级别
等待时系统栈如何? 栈底是目态现场,然后是嵌套函数的返回点,参数,局部变量,返回值;如有嵌套,接下来是核心现场,然后是嵌套函数的返回点、参数、局部变量、返回值;(可能有多重)
中断分析,关于剥夺
何时等待剥夺? 处于核心态,无嵌套中断或有嵌套
等待剥夺几次? 可能多次
保存在PCB的是什么级别现场? 核心级别
剥夺时系统栈如何? 栈底是目态现场,然后是嵌套函数的返回点,参数,局部变量,返回值;如有嵌套,接下来是核心现场,然后是嵌套函数的返回点、参数、局部变量、返回值;(可能有多重)
step1:
step2:
setp3:
step4:如果发生等待
step5:(如果等待的资源就绪orIO中断结束,
step6:
(可能多次等待....)
step7:
其他情况:
step4:如果在user发生中断嵌套:
step4:如果发生嵌套中断
step5:嵌套返回
step6:最后一层:
其他情况
step4:发生剥夺
step5 : end:
-8:具体的一些中断处理
--1:IO中断处理:
----:正常的结束:
继续传输并唤醒相关进程
----:传输错误:
复执(3次,5次)
报告系统操作员
--2:时钟中断处理:
进程管理: 重新计算进程调度参数(eg:动态优先数)
作业管理: 记录作业在输入井中等待的时间,以及当前的优先级别,以便作业调度
资源管理: 动态统计运行进程占有和使用处理器等资源的时间
事件处理: 在实时系统中定时向被控对象发送控制信号
系统维护: 定时运行死锁检测程序和记账程序
实现软时钟: 运用硬件间隔时钟和一个存储单元
利用硬时钟:10ms一次,我们的软时钟初始化为10,那么没一次中断-1,到0则计时100ms
-3:控制台中断程序:
一个控制按钮,一个中断向量,一个中断处理程序
--4:硬件故障处理:
----掉电:
内存,寄存器->外存
停止设备
-----停止处理机
恢复:
启动处理机
启动设备
外存->内存,寄存器
-----内存故障处理
海明校验,奇偶校验错误
下雨检查
划出系统
报告操作员
-9:程序性中断的处理:
-只能OS处理的中断:
影响系统或其它进程: 越界,非法指令,(处理:终止进程、调试)
需要系统管理或协助: 页故障,缺段,(处理:动态调入)
-可以由用户自己处理的中断
不影响系统和其它进程: 除0,溢出,(处理:用户处理,或OS处理)
on <中断条件> goto 中断元入口
(相同的错误不同位置可以不同的处理)
-10:中断处理过程:
编译时:生成中断续元表:
执行时:执行调试语句,填写上面的表
中断时:根据中断原因查表,
如果不是0,使用用户规定的中断续元,用户处理
如果是 0 ,OS标准处理
处理的步骤:
(1)发生溢出中断
(2)保存旧PSW和PC
(3)取中断向量
(4)转到中断处理程序
(5)访问中断续元表(假定非0)
(6)系统栈中现场转移到用户栈
(7)中断续元入口送寄存器(OS中断处理完成)
(8)执行中断续元
(9)完成后执行RET指令由用户栈PSW和PC送寄存器
(10)返回中断断点
-11:自愿中断的处理:
--访管指令:
准备参数
SVC n (supervisor call)
取返回值
--系统调用:
返回值=系统调用名称(实参1,…,实参n)
不同的系统提供的服务在数量和种类上各有差别,通常分为:
与文件有关的:建立文件、撤销文件、打开文件、关闭文件、读写文件、文件指针定位
与进程有关的:创建进程、撤销进程、创建线程、监督进程运行状况
与通信有关的:发送消息、接收消息
与同步有关的:P操作、V操作
二:处理机调度
2-1:处理机调度算法:
前置概念:
我们需要考虑什么?
CPU利用率 ; (max)
吞吐量 ; (max)
周转时间 ; (min):T=完成时间-进入时间
平均周转时间=∑T/n
带权周转时间:W=T/R (周转时间/运行时间)思路是我一个1s的程序你让我等99s就很糟糕
平均带权周转时间:∑W/n
响应时间 ; (min)
系统开销 ; (min)
阵发期:
CPU阵发期:进程(线程)使用CPU计算
IO阵发期:进程(线程)使用设备I/O
进程的运行行为就是在两个阵发期之间来回横跳,我们的CPU调度算法就是用来考虑CPU阵发期进程集合的调度的
阵发期估值:
参数α(0≤α≤1)控制tn和τn在公式中起的作用:当α=0时,τn+1=τn;当α=1时,τn+1=tn。通常α取0.5。
2-1-1:FCFS算法:先到先服务,逻辑很简单
举例:
先服务P1,然后P2,最后P3,发现如果是先来了一个大家伙,大家就必须都得等着
Gantt图:
一些计算:
评价:
优点:’公平’
缺点:短作业或进程、线程等待时间长。
2-1-2:SJF短作业优先算法:思路也很简单,谁的所需时间短,谁先
Gantt图:
也很容易发现大作业可能被一堆小作业给饿死
一些计算:
评价:
假定所有任务同时到达,平均等待时间最短。
长作业可能被饿死。
2-1-3:SRTN最短剩余时间优先算法:谁目前 最快完成,就去服务谁:
Gantt图:
从运行发现,一会服务1,一会中断去服务其他的,一看就代码比较麻烦,切换来切换去的系统开销也大,而且也没解决大作业被饿死的问题
2-1-4:HRN最高响应比优先:
RR=(BT+WT)/BT (BT是阵发期时间,WT是等待时间)
发现这个:
同时到达任务, 短者优先
长作业随等待时间增加响应比增加
比较综合了,但是带来的问题是实现复杂(中间不会剥夺)
2-1-5:HPF最高优先数有限算法:
这个根据优先数从高到低运行,当然优先数可以两个方式去设定:
静态优先数(static):
优先数在进程创建时分配,生存期内不变。
简单,开销小。
公平性差,可能会造成低优先数进程长期等待。
适合批处理进程
动态优先数(dynamic)
进程创建时继承优先数,生存期内可以修改。
获得资源优先数提高
就绪时随等待处理机时间增长而提高
资源利用率高,公平性好。
开销大,实现复杂。
当然,调度策略也分为两种:
剥夺式(preemptive抢先):
就绪进程可以从运行进程手中抢占CPU。
进程运行,直到结束、等待、出现新的高优先数就绪进程.
进程切换频繁系统开销较大,但保证当前运行进程是系统内可运行进程中优先数最大的
非剥夺式(non-preemptive非抢先)
就绪进程不可从运行进程手中抢占CPU。
进程运行,直到结束或等待
优点:系统开销较小
缺点:不能保证当前正在运行的进程永远是系统中当前可运行进程中优先数最高的进程
评价:
非剥夺式静态优先数:
获得处理机的进程运行,直至终止or等待
系统开销小,但不能保证正在运行的进程是可运行进程中优先数最高的
剥夺式动(静)态优先数
获得处理机的进程运行,直至终止or 等待 or出现高优先级的进程
进程切换频繁,系统开销大,但是能保证正在运行的进程是当前可运行进程中优先数最高
举例(可剥夺):
Gantt图:
一些计算:
(如果一些大任务是高优先的,就会导致大面积的饿死,当然,实时系统必然是要求高优先的先处理的)
2-1-6:RR循环轮转算法:
时间片:将CPU的执行时间分成若干片段
所有进程按所分得的时间片的长短轮流运行
所有就绪进程排成一个队列形成就绪队列,当CPU空闲时取就绪队列队首进程执行,同时给该进程分配一个时间片,当时间片用完该进程若还需要CPU时间(CPU阵发期没结束)则剥夺该进程所占有的处理机,将其排在就绪队列末尾,并选择就绪队列队首的进程运行.如果服务完成,选择就绪队列队首的进程运行
两类轮转算法:
基本轮转
时间片(quantum,time slice)长度相同,固定不变;不考虑数据传输等待因素,系统中所有进程等速向前推进。
改进轮转
时间片长度不同,可变。系统可以根据不同进程的不同特性为其动态地分配不同长度的时间片,达到更灵活的调度效果
(适用于分时系统:公平,且响应及时)
举例(基本轮转):
Gantt图:
一些计算:
2-1-7:分类排队法:
多级队列
多个就绪队列,进程所属的队列固定。
实现各个进程所期望的调度目标
例如:通用系统中:
队列1:实时进程就绪队列(HPF)
队列2:分时进程就绪队列 (RR)
队列3:批处理进程就绪队列 (HPF)
执行顺序:1、2、3 #在这就有优先级了
2-1-8:FB反馈排队算法:
多个就绪队列,循环轮转,进程所属队列可变
(先执行高优先级的,有一点暗含高优先级服务高变为最低优先级的意味)
调度效果:
短进程优先处理
运行时间短的进程在前面几个队列之后就可以执行完,而前面队列优先级高是被优先调度的。
设备资源利用率高
交互式进程经常进入等待状态(等待用户输入),一旦被唤醒(输入完成),进入最高级队列,可尽快被调度选中,投入运行,可以尽快使用设备;
系统开销小
计算量大的进程用完前面n-1级时间片,没有处理完,落入底层队列,调度频率下降,但每次获得较长的时间片。
可以根据原则将低优先级进程上移
2-2:处理机调度时机:
处理机调度程序是OS底层的一个模块,除非显示地被调用,否则不可能主动运行,其运行的时机有:1,运行进程结束;2,运行进程等待;3,处理机被剥夺;
中断是进程切换的前提但不是充分条件!!!!!!
中断:
必然引起进程切换的中断:
1,进程自愿结束, exit()
2,进程被强行终止
3,非法指令(越界,kill)
4,进程等待
可能引起进程切换的中断
1,时钟
2,系统调用
2-3:处理机调度过程:
在关中断情况下进行:
保存下降进程的现场:寄存器(PSW,PC,SP,通用寄存器,地址寄存器)ÞPCB
选择上升进程:按处理机调度算法(处理机调度程序)
恢复上升进程的现场:
PCB->寄存器:先恢复通用寄存器、地址寄存器和SP,最后恢复PSW,PC(PSW和PC必须用一条指令恢复)
()UNIX
三:调度级别和多级调度
低级调度:
前面的微观的处理机调度
中级调度和交换
(内存和外存的交换)
目标:用来控制并发度(过低,效率低,过高,系统开销,响应,内存占用多,频繁等待(资源被占用))
交换:内存和外存的交换
根据这个中级调度算法,我们可以更细致的把就绪和等待分为:就绪(内存)+就绪挂起(外存),等待(内存)+等待挂起(外存)
如果内存够,就直接拉入内存,否则就外存就绪(挂起)
如果内存不够的话,需要换出,优先考虑等待状态,其次就绪状态
且,等待挂起->等待的收益不大,一般也不考虑,那不如先就绪等待->等待
UNIX的中级调度(sched#0)
:把外存的就绪移入内存(内存够)or先移出(SWAIT(不急迫的等待)和SSTOP跟踪)在尝试,如果还不够:移出SSLEEP(急迫等待事件)和SRUN,再去尝试
实现调度的前置条件:
待移入的进程在外存等待3秒and 待移出的进程在内存超过2秒
高级调度和作业
(作业从输入井->内存->进程...)
批处理作业:程序+数据+说明书
作业结果:账单+数据结果
输入机-通道-输入井传输(提交)->输入井(后备)-作业调度(高级)->主机(执行)-(作业控制)->输出井->输出井-通道-输出机->退出
(通道对主机打扰少)
作业控制块+作业表:
JCB:标志作业存在的数据机构,保持系统对作业进行管理的全部信息
批处理作业调度:
(
适合高级调度的算法:FCFS.HPF,SJF,HRN
不适合的算法:RR,SRTN,FB(剥夺式算法)
)
四:实时调度
(针对实时任务,有明确的截止期限or明确的开始时间)
实时调度:合理安排继续实时任务的性质那个次序,满足每个实时任务时间约束条件
实时也分为:硬实时(会有严重后果)+软实时(不会有严重后果)
实时也分为:周期性(固定间隔触发)+随机性(不固定,随时触发)
周期性实时调度
可调度的必要条件:(我们让C为任务的处理时间,T为任务的发生周期)
任务p1~pn可调度:
两个实时算法:
EDF:
优先选择截止期早的任务,可以调度的所有任务
RMS:
非剥夺式,先调度发生周期短(f高):可调度
大概的表:
五:多处理机调度
目的:实现负载均衡(每个处理机一个就绪队列可能不均衡,,如果共同一个,可以均衡)
M进程+N处理机
一般都是讲的SMP,对称多处理机
算法:
自调度:
一个就绪队列
优点:任务分配均衡
缺点:
CPU过多,就绪队列成为了瓶颈.
同一个线程的两次调度可能在不同的处理机(二级缓存没用啦!!!!!!)
不能保证合作进程同时调度(生产者和消费者一起调度,可能是生产者没原料了,等待消费者)
(优化的自调度:
一个全局对列(对应系统)
多个局部队列(对应CPU)
调度先看局部,然后全局
)
组调度:
一组相关的(合作)线程同时分配到多个处理机上(
减少相互等待,降低开销,提高运行效率
)
六:系统举例
Linux调度:
三种特征进程:(软实时
Real-time FIFO
Real-time RR
Timesharing
基于Goodness(priority 和 counter决定)
priority:0~40 越大越好,默认20
(对比UNIX,-20~20,越小越好)
counter:进程尚可运行时间,对于运行进程,每10ns,counter-1,所有的就绪的counter降到0时,重新计算所有进程的counter(counter = counter/2 +priority
goodness计算:
什么时候调度:
1-运行进程的counter为0
2-进程自己调用exit
3-进程等待 IO or 信号灯
4-被高优先剥夺
效果:实时>分时,交互和IO>CPU进程
windows调度;
2000/XP线程调度:
线程类型:
real time(软实时)
foreground :GUI窗口,交互
background:后台
调度算法:preemptive + dynamic priority +RR + feed back (支持SMP)
有32个优先级
实时系统线程:高优先级:(16-31):
一些内核线程,其他应用要提升需要一定权限,软实时
可变用户线程:低优先级(1-15):
基本优先级:
线程继承进程+-2,不变的
当前优先级:
基本优先级-15之间,可以动态提升,但是运行一个quantum会下降(>=基本,<=15)
调度看当前优先级
系统优先级:0,页面清0:
对空闲物理页面做清0,目的是希望一个进程需要清0一个页面时,不需要等待.(这个活也可能被其他(现清0)给做了)
当然也不一定分配的进程都要是请0的,比如fork(),带着父进程的数据覆盖区域
优先级提升:(不超过15)
-IO结束->继续传输时
-事件等待结束->尽快处理
-前台唤醒一个等待进程->尽快处理
-窗口活动唤醒的GUI->及时响应
-就绪超过一定期限->防止饥饿
抢先:
-被唤醒的线程优先级高于运行线程优先级
-就绪线程优先级动态变化(提升)
被抢先的线程:
回到就绪+(实时:分配完整时间片,其他:不变)
quantum:
范围:6-36
15ms的时钟,一次-3,(2-12个时钟)
配额用完会进入就绪队列,优先级降低
为了SMP上的线程调度:(同一个线程尽量在同一个处理机上运行:利用2级缓存)
亲和关系:
每个进程有一个处理器亲和掩码,缺省就是全部处理机(线程继承进程)
理想处理器:
线程有两个理想处理器(首选+第二,记录在内核TCB,在线程创建的时候随机确定的)
线程对处理器的选择:
有空闲:首选>第二>当前(调度的CPU)>从高到低找空闲
无空闲:抢先顺序:首选>第二>可运行编号最大 都不行回到就绪
处理器对线程:
空闲的CPU:选择上次在这运行的>理想型是我的>就绪超过2个quantum的>优先级别>=24