操作系统
第一章
操作系统的定义
计算机系统中控制和管理计算机系统资源,合理组织计算机工作流程,提高资源利用率和方便用户使用计算机系统的计算机程序的集合
操作系统的目标
- 方便性
- 有效性
- 可扩充性
- 开放性
操作系统的作用
- 用户与计算机硬件系统之间的接口
- 计算机系统资源的管理者
- 实现对计算机资源的抽象
单道批处理系统(最早的操作系统)
- 优点:一定程度上缓解了人机速度矛盾
- 自动性,顺序性,单道性
- 主要的缺点:系统中的资源得不到充分利用
多道批处理系统(真正的操作系统开始出现)
- 优点:多道程序并发执行,资源利用率提高
- 缺点:无序性,无交互性能力,平均周转时间长
- 需要解决的问题
- 处理机争用问题
- I/O设备分配问题
- 文件的组织和管理问题
- 作业管理问题
- 用户与系统的接口问题
批处理特点
- 多道性、无序性、调度性,系统利用率高、吞吐量大、平均周转时间长、但无交互能力
分时系统(用户需求)
- 满足用户对人机交互的需求
- 实现的关键问题
- 如何使用户能与自己的作业交互
- 人-机交互
- 共享主机
- 缺点:不能优先处理紧急任务
- 特征
- 多路性
- 独立性
- 及时性
- 交互性
实时系统
- 相比于分时系统对时间更敏感
- 优点:能优先处理紧急任务
- 特征
- 及时性
- 多路性
- 独立性
- 交互性
- 可靠性
实时系统与分时系统的比较
- 实时系统特点:主动权在用户,用户规定什么时间要计算机干什么,机器不能“走开”;实时操作系统追求在尽量短的时间完成用户工作。
- 分时系统特点:主动权在计算机,计算机按一定时间间隔,以固定时间片段或不固定时间片去轮流完成多个提交的任务,在用户反应相对较慢时,不感到机器“走开”。
操作系统的基本特征(并发和共享是OS最基本的特征)
并发:两个或多个事件在同一时间间隔发生
- 并行:两个或多个事件在同一时刻发生
共享:系统中的资源可供内存中多个并发执行的进程共同使用
- 互斥共享方式
- 系统中的某些资源,可以提供给多个进程(线程)使用,但是在规定的时间内,只允许一个进程访问该资源
- 同时访问方式
- 系统中的另一类资源,允许在一段时间内由多个进程“同时”对它进行访问
虚拟:在OS中,把通过某种技术将一个物理实体变为若干个逻辑上对应物的功能称为虚拟
- 时分复用技术
- 利用处理机的空闲时间运行其他程序,提高处理机的利用率
- 空分复用技术
- 利用存储器的空闲空间分区域存放和运行其他的多道程序,以此提高内存的利用率
异步:进程是以人们不可预知的速度向前推进的
操作系统的主要功能
- 处理机管理功能
- 主要功能有:创建和撤销进程,对诸进程的运行进行协调,实现线程之间的信息交换,以及按照一定的算法把处理机分配给进程
- 进程控制、进程同步、进程通信、调度
- 存储器管理功能
- 主要任务:是为多道程序的运行提高良好的环境,提高存储器的利用率,并能从逻辑上扩充内存
- 具备:内存分配和回收,内存保护,地址映射和内存扩充
- 设备管理功能
- 文件管理功能
操作系统的结构设计
- 无结构操作系统:庞大又杂乱,缺乏清晰的结构
- 模块化结构OS:将OS按其功能划分为若干个具有一定独立性和大小的模块
- 优点:提高OS设计的正确性,可理解性和可维护性。 增强OS的可适应性 加速OS的开发过程
- 缺点:难以满足在模块设计完成后对接口的实际需求。OS设计阶段,设计者必须作出一系列决策
- 分层式结构OS
- 优点:系统正确性,易扩充性和易维护性
- 缺点:系统效率降低
- C/S模式
- 优点:数据的分布处理和存储,便于集中管理,灵活性和可扩展性,易于改编应用软件
- 缺点:不可靠性,瓶颈
- OOP模式
- 优点:通过"重用"提高产品质量和生存率,使系统具有更好的易修改性和扩展性,更易于保证系统的"正确性"和"可靠性"
死锁
死锁产生的原因:竞争资源,进程间推进顺序非法
资源类型: 1.可重用性资源和消耗性资源 2.可抢占性资源和不可抢占性资源
计算机系统中的死锁:
- 竞争不可抢占性资源引起死锁
- 竞争可消耗资源引起死锁
- 进程推进顺序不当引起死锁
- 死锁:进程中的每一个进程都在等待仅由该组织进程中的其它进程才能引发的事件,那么该组进程是死锁的。
- 产生死锁的必要条件:1.互斥条件 2.请求和保持条件3不可抢占条件
- 循环等待条件
外理死锁的方法: 1.预防死锁 2.避免死锁3.检测死锁 4…解除死锁
预防死锁:破坏"请求和保持"条件,破坏"不可抢占"条件,破坏循环等待条件避免死锁:在资源动态分配过程中,防止系统进入不安全状态
安全状态:系统能按某种进程推进顺序为每个进程分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都 可顺利地完成
银行家算法P121
资源分配图P123
死锁定理:对资源分配图进行化简来检测是否死锁
存储器管理
存储器的结构层次
- 存储层次:CPU寄存器,主存,辅存为了实现存储器的速度,要求有大容量,价格便宜。
- 层次越高(越靠近CPU),存储介质的访问速度越快,价格也越高,相对所配置的存储容量越小。
- 主存是计算机系统中的主要部件,用于保存进程运行时的程序和数据
- 寄存器具有与处理机相同的速度。故对寄存器的访问速度最快,完全能与CPU协调工作,但价格昂贵,容量小
程序的装入与链接
程序的运行:编译→链接→装入
程序的装入:a、绝对装入方式 b.可重定位装入方式C.动态运行时的装入方式程序的链接:静态链接,装入时动态链接,运行时动态链接
连续分配存储管理方式
单一连续分配:内存的系统区和用户区两部分,系统仅提供给OS使用,而用户区内存中,仅装有一道用户程序,整个空间被该程序独占
固定分区分配
- 将用户空间划分为若干个固定大小的区域,每个分区只装个作业
- 划分分区的方法:分区大小相等(缺乏灵活性,造成内存空间的浪费,适用于一台计算机控制多个相同对象的集合), 分区大小不等(增加分配的灵活性)
内存分配:
动态分区分配:根据进程的需要,动态地为之分配内存空间
分区分配操作P138:分配内存,同收内存动态分区分配算法:
a. 首次适应算法
空闲分区链以地址递增的次序链接
在分配内存时,从链首开始顺序查找, 直至能找到一个大小能满足要求的空闲分区为止按作业大小,从该分区中划出一块内存空间,分配给请求者,余下的空间分区仍留在空闲链中
优点:优先利用低址区的空闲分区,保留了高址区的空闲分区, 缺点:留下很多空间分\区碎片,增加查找可用空闲分区时的开销
b. 循 环首次适应算法
与上面的空闲分区链一样
不是每次从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直到找到满足要求的空闲分区从中划分块与请求大小样的内存空间分配给作业
优点:内存中的空闲分区分布得更均匀,减少查找空闲分区的开销。缺点:缺乏大的空闲分区
c. 最 佳适应算法
将所有空闲分区按其容空间大小从小到大形成空闲分区链从链首开始查找,直到找到满足要求的空闲分区,从中分隔一部分存储空间给作业
优点:产生外部碎片小,无内部碎片 缺点:会产生许多难以利用的碎片
d. 最坏适应算法
将所有空闲分区按其容量以从大到小的顺序形成一空闲分区链在扫描整个空闲分区表,总是挑选一个最大的空闲区从中分隔一部分存储空间给作业
优点: 剩下的空闲分区不至于太小 查找效率高基于索引搜索的动态分区分配算法
e.动态重定位分区分配算法
对换
把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以便腾出足够的内存空间,再把已具备运行条件的进程或进程所需要的程序和数据换入内存
对换的类型: 1. 整体对换 2.页面(分段)兑换
每次对换都是将一定数量的程序或者数据换入或换出内存
对换空间的管理: 1.文件区2.对换区
对文件区的目标:提高文件存储空间的利用率,其次提高文件的访问速度
对对换区的目标: 提高进程投入和换出的速度,其次提高文件存储空间的利用率
对换区空闲块管理中的数据结构:对换区的首址和大小,分别用盘块号和盘块数表示
第二章
早期未配置OS的系统以及单道批处理系统顺序执行内存只装入一个程序
独占所有系统资源
程序执行完成后才装入下个程序资源浪费,系统运行效率低
传统OS以及现代OS程序并发执行内存同时装入多道程序
共享资源,并发执行
前趋图
有向无循环图
描述进程之间执行的先后顺序
每个结点表示一个进程或程序段,乃至一条语句有向边表示两个结点之’间的前趋关系
直接前趋。直接后趋,初始结点,终止结点
程序的执行顺序(单):I→C→P 输入→计算→打印。程序执行的特征(单)
顺序性:严格按照程序规定的顺序执行
封闭性:独占全部资源,不受外界影响
可再现性:只要执行环境和初始条件相同,得到相同结果
多道批
- 程序的并发执行
- 程序顺序执行方便调试程序。但资源利用率低、多道批和并发执行提高资源利用率
- 不存在前趋关系的程序之间才有可能并发执行
- 程序并发执行的特征
- 间断性:相互制约关系导致程序执行
- 失去封闭性:程序运行环境受到其它程序影响
- 不可再现性:程序计算结果与并发程序运行速度有关(进程调度)
进程
定义
- 程序的一次动态执行
- 进程的定义:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位
特征
- 动态性,并发性,独立性,异步性,结构性
进程实体(进程实体是独立运行,独立获得资源,独立调度的基本单位)
- 程序段
- 相关的数据段
- 进程控制块(PCB)
- PCB:进程控制块(PCB)作用:为了参与并发执行的每个程序都能独立运行,在操作系统中必须为之配置一个专门的数据结构
程序与进程的比较
- 程序是静态的观念,进程是动态的观念
- 进程具有并发性,程序没有并发性
- 进程是竞争计算机资源的基本单位,而程序不是
- 一个程序可以对应多个进程及多个进程可以执行同一个程序,一个进程可以执行一个或多个程序
- 程序是永存的,而进程是暂时的,进程由创建而产生,由调度而执行,由撤销而凋亡
状态及状态转化
- 三种基本状态:
- 就绪状态:分配到除CPU以外的所有必要资源
- 执行状态:进程获得CPU
- 阻塞状态:正在执行的进程由于发生某事件(如I/O请求,申请缓存区失败等)暂时无法继续执行时的状态
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VFEJqxpG-1678504844260)(.\image-20221206183501627.png)]
- 引发状态转化事件
- 就绪–>执行:进程调度
- 执行–>就绪:时间片完
- 执行–>阻塞:I/O请求
- 阻塞–>就绪:I/O完成
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mogJEktK-1678504844262)(.\test.png)]
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BQyKdKaw-1678504844263)(.\image-20221206183934749.png)]
- 创建状态
- 进程所需的资源尚不能得到满足,此时创建工作尚未完成,进程不能被调度运行,此时进程所处的状态
- 创建步骤
- 1、申请一个空白的PCB,并向PCB中填写用于控制和管理进程的信息
- 2、为该进程分配运行时所必须的资源
- 3、把该进程转入就绪状态并插入就绪队列之中
- 目的:为了保证进程调度必须在创建工作完成后进行,以确保对进程控制块的完整性;也增加了管理的灵活
- 终止状态
- 创建步骤
- 1、等待操作系统进行善后处理
- 2、将其PCB清零,并将PCB空间返还系统
- 挂起状态
- 引入原因是基于系统和用户的如下需要:
- 终端用户的需要:方便用户研究程序执行情况或对程序进行修改
- 父进程请求:挂起自己的子进程,以便考查和修改子进程或者协调各子进程间的活动
- 负荷调节的需要:实时系统工作负荷较重,把一些不重要的进程挂起,以保证系统正常运行
- 操作系统的需要
- 挂起原因:当系统资源尤其是内存资源已经不能满足进程运行的要求时,必须把某些进程挂起(suspend),对换到磁盘对换区中,释放它占有的某些资源,暂时不参与低级调度。起到平滑系统操作负荷的目的。
- 进程的终止过程:等待OS进行善后处理,将其PCB清0,并将PCB返还系统
- 进程的挂起:处于静止状态,不接受调度,与激活对应终端用户需要父进程请求负荷调节需要操作系统需要
系统为每一个资源和进程设置一个数据结构。
4类数据结构:内存表,设备表,文件表,进程表(PCB)
进程与程序的比较
- 程序是静态的观念,进程是动态的观念
- 进程具有并发性,而程序没有并发性
- 进程是竞争计算机资源的基本单位,而程序不是
- 一个程序可以对应多个进程及多个进程可以执行同一程序,一个进程可以执行一个或几个程序
- 程序是永存的,而进程是暂时的
- 进程由创建而产生,由调度而执行,由撤销而消亡
进程控制
OS最内层的部分称为内核,内核部分常驻内存(硬件紧密相关的模块,常用设备驱动程序,运行频率较高的模块)
OS分层目的:便于如软件保护,防止受到其他应用程序的破坏,提高OS的运行效率
处理机状态:系统态(管态,内核态)和用户态(目态)
原子操作(不允许中断):一个操作中的所有动作要么全做,要么全不做,不可分割
原语操作(不允许中断):由若干条指令组成,用于完成一定功能的一个过程
内核的支撑功能:中断管理,时钟管理,原语操作
内核的资源管理功能:进程管理,存储器管理,设备管理
进程图:描述一个进程的家族关系,有向图
图中结点代表进程,创建父进程的进程称为祖先进程,子进程,父进程
引起创建进程的事件:用户登录,作业调度,提供服务,应用请求
进程的创建:
- 申请空白PCB,为新进程申请PCB
- 为新进程分配运行所需资源,包括各种物理和逻辑资源
- 初始化PCB
- 如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列
进程的终止事件:
- 进程正常结束
- 进程异常结束
- 外界干预
进程的终止过程:
进程的阻塞事件:
- 进程的阻塞过程(自身阻塞):
- 进程唤醒:
进程同步
基本概念
- 进程同步的任务
- 对多个相关进程在执行次序上协调
- 使并发进程有序(按规则)使用共享资源,并互相合作
- 使程序执行具有再现性
- 临界资源:一段时间内只允许一个进程访问的资源
- 多个进程必须互斥地访问临界资源
- 临界区:每个进程中访问临界资源的那段代码
- 临界区前面检查是否可进入的部分称为进入区
- 临界区后面恢复临界区访问标志的部分称为退出区
- 同步机制应遵循的准则
- 空闲让进
- 忙则等待
- 有限等待
- 让权等待
硬件同步机制
- 关中断
- Test-and-set:允许对一个字中的内容进行检测和修正
- swap:对两个字的内容进行交换
进程间的两种制约关系
- 间接相互制约关系(抢)
- 并发进程对共享资源的互斥访问
- 并发进程对临界资源互斥访问
- 直接相互制约关系(接力)
- 由于多个并发进程相互合作完成同一任务
- 例如输入,计算,输出
信号量机制
整型信号量
表示资源数目的整形量S
除初始化外,仅能通过原子操作wait(S)和signal(S)访问
wait也称P操作,signal也称V操作
P操作(wait)定义:申请一个单位资源,进程进入
- 将信号量S的值减1,即S=S-1;
- 如果S<=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列
V操作(signal)定义:释放一个单位资源,进程出来
- 将信号量S的值加1,即S=S+1;
- 如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S3xfHU71-1678504844267)(.\image-20221208142736175.png)]
P(s)->临界区->V(S)
int S=1;//整型信号量,代表某种资源的数目。 void wait(int S) #相当于进入区 { while(S<=0); //资源数不足,循环进入等待 S=S-1; //申请到资源,对应资源减一 } void signal(int S) #相当于退出区 { S=S+1; //使用完资源之后,释放对应资源 }
整型信号量有"忙等"问题,未遵循"让权等待"的准则
互斥:在临界资源分别PV;同步:前V后P
- 整型信号量和记录型信号量是共享一个临界资源
记录型信号量
不存在"忙等"现象
除需要代表资源数目的整型变量value外,还增加一个进程链表指针list,用于链接上述的所有等待进程
typdef struct { int value; //剩余资源数 struct process *L; //等待队列 } semaphore//;信号量 void wait(semaphore S) { S.value--; if(S.value <0) block(S.L); } void signal(semaphore S) { S.value++; if(S.value <=0) wakeup(S.L); }
AND型信号量
整型信号量和记录型信号量适用于仅共享一个资源,多个临界资源可能会引起死锁
A,B两个进程访问D,E两个共享数据
两个信号量Dmutex,Emutex(下图死锁)
AND型信号量基本思想:将进程运行所需资源一次性全部分配,使用完后一次性释放.若一个资源不能满足,则其他也不分配
AND型信号量一次申请多个临界资源,若有一个不满足则一个也不分配
Swait(S1,S2…Sn) Ssignal(S1,S2…Sn)
wait(S1, S2, …, Sn) { While(TRUE) { if (S1 >=1 and … and Sn>=1 ){ for( i=1 ;i<=n; i++) Si--; break; } else{ Place the process in the waiting queue associated with the first Si found with Si < 1,and set the progress count of this process to the beginning of Swait operation } } } signal(S1, S2, …, Sn){ while(TRUE){ for (i=1; i<=n; i++) { Si++ ; Remove all the process waiting in the queue associated with Si into the ready queue } } } 进程一次申请所有需要的资源可避免死锁
信号量集
- 对AND信号量扩充,PV操作中指出每类资源申请数量(d)、分配下限值(t)S>t才分配
经典进程同步问题
生产者消费者问题描述
- 生产者消费者是相互合作进程关系的抽象:输入,计算,输出
- 一群生产者生产产品供消费者去消费
- 共用有n个缓冲区的缓冲池
- 生产者的产品放入池中,消费者从池中取产品消费
- 生产者消费者要同步,池满时停止生产,池空时停止消费
- 必须互斥访问临界资源(公共变量)
记录型信号量解决生产者-消费者
int in=0,out=0; item buffer[n];//缓冲区 semaphore mutex=1;//互斥信号量 semaphore empty=n,full=O;//资源信号量 //生产者(空缓冲区数量) //消费者 void main(){ cobegin//开始(里面的并发执行) producer(); consumer(); coend//结束(里面的并发执行) } void producer(){//生产者进程 do{ produce an item nextp;//生产产品放入nextp,后续判断放入缓冲区 ... wait(empty);//不能颠倒,判断是否有空缓冲区 wait(mutex);//不能颠倒,申请操作权限,其他进程不能使用 buffer[in]=nextp;//临界区 in=(in+1)%n;//临界区,指针向后拨 signal(mutex);//释放互斥锁,给其他进程使用 signal(full);//唤醒消费者 full加一 }while(TRUE); } void consumer{//消费者进程 do{ wait(full)://不能颠倒//进入区,full大于0通过 wait(mutex)://不能颠倒//进入区,申请操作权限,其他进程不能使用 nextc=buffer[out];//临界区 消耗缓冲区 out=(out+1)%n;//临界区 signal(mutex);//退出区 释放互斥锁,给其他进程使用 signal(empty);//唤醒生产者//退出区 empty加一 comsume item in nextc; ... }while(TRUE); }
AND信号量解决生产者消费者
int in=0,out=0; item buffer[n];//缓冲区 semaphore mutex=1;//互斥信号量 semaphore empty=n,full=O;//资源信号量 //生产者 //消费者 void main(){ cobegin//开始(里面的并发执行) producer(); consumer(); coend//结束(里面的并发执行) } void producer(){ producer)进程 do{ produce an item nextp; .... Swait(empty,mutex);//进入区,empty>0且判断是否被人使用,通过向下 buffer[in]=nextp;//临界区 in=(in+1)%n;//临界区 Ssignal(mutex,full);//退出区 ,互斥锁释放,full加一 }while(TRUE); } void consumer(){//消费者进程 do{ Swait(full,mutex);;//进入区,无人占用且full>0通过 nextc=buffer[out];//临界区 out=(out+1)%n;//临界区 Ssignal(mutex,empty);//退出区,互斥锁释放,empty加一 comsume item in nextc; }while(TRUE); }
哲学家就餐问题
问题描述
- 五位哲学家围圆桌就餐,共5只筷子
- 只有拿到左右两只筷子才可就餐
记录型信号量解决哲学家就餐
筷子为临界值 ,初值为1
可能引起死锁
解决办法
- 至多允许四位去拿筷子
- 仅当左右筷子都可用才就餐
- 奇数先拿左筷子,偶数先拿右筷子
semaphore ch[5]={1,1,1,1,1}; //第i个哲学家进程 do{ wait(ch[i]);//进入区 拿左边筷子 wait(ch[(i+1)%5]);//进入区 拿右边筷子 ...eat... signal(ch[i]);//释放左边筷子 signal(ch[(i+1)%5]);//释放右边筷子 ...think... }while(TRUE);
AND型信号量解决哲学家就餐
semaphore ch[5]={1,1,1,1,1}; 第i个哲学家进程 do{ Swait(ch[(i+1)%5],ch[i]);//同时获得两个临界资源才就餐,无死锁 ...eat... Ssignal(ch[(i+1)%5],ch[i]); ...think... )while(TRUE);
读者写者问题
问题描述
- 多个读者可以同时访问临界资源(读取)
- 一次最多一个写者访问临界资源(写入)
- 不允许读者和写者同时访问
- 与文件访问类似
- 实质是要保证写进程与其它进程互斥访问共享资源
记录型信号量解决
wmutex用于reader,writer互斥访问临界资源
rmutext用于互斥访问readcount(正在读的进程数目)
semaphore rmutex=1;//用于互斥访问readcount semaphore wmutex=1;//保证读者和写者互斥访问 int readcounta=O;//readcount表示正在读的进程数目 //writer进程: do{ wait(wmutex);//判断有没有读者或者写者在访问资源 //执行写操作 signal(wmutex);//释放互斥锁给其他进程使用 }while(TRUE); //reader进程: do{ wait(rmutex);//判断有没有读者在访问资源 if(readcount==O)wait(wmutex);//第一个读者,并且阻止其他写者进程 readcount++; signal(rmutex);//释放读互斥锁 //执行读操作 wait(rmutex);//判断有没有读者在访问资源 readcount--; if(readcounta==O)signal(wmutex);//最后一个读者,释放写者锁,允许其他写者进程访问 signal(rmutex);//释放写者互斥量 }while(TRUE);
进程通信类型
- 共享存储器系统
- 管道通信系统
- 消息传递系统
- 客户机-服务器系统
线程
目的
- 减少程序在并发执行时所付出的时空开销,使OS有更好的并发性
概念
- 作为独立调度和分派的基本单位,因而是独立运行的基本单位
- 线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程中⾄少有⼀个线程
三种状态
- 执行状态:表示线程已获得处理机而正在运行
- 就绪状态:线程已具备除CPU外各种执行条件
- 阻塞状态:线程因某事件受阻而处于暂停状态
进程与线程
进程的目的:使多个程序能并发执行,以提高资源利用率和系统吞吐量。进程是拥有资源和独立调度的基本单位
进程的两个基本属性
进程是可拥有资源的独立单位:程序正文、数据的磁盘空间和内存空间,申请的I/O设备、已打开的文件,信号量等
进程是可独立调度和分派的基本单位
- 每个进程有唯一PCB,系统根据PCB感知进程的存在
- 根据PCB中的信息,对进程进行调度
- 利用PCB进行现场保护和恢复
程序并发执行会出的时空开销
- 进程并发时的开销
- 创建进程
- 撤销进程
- 进程切换
- 进程是资源拥有者,创建、撤消、切换开销很大
- 进程数目不能太多,i学呈切换不宜太频繁,限制并发程度
线程的引入
- 多处理机系统都有线程机制
- 线程做为调度和分派的基本单位
线程与进程的比较
- 调度的基本单位:在引入线程的操作系统中,把线程作为调度和分派的基本单位,而进程作为资源拥有的基本单位
- 处理器调度:线程是处理器调度的基本单位。
- 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
- 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步
- 处理机分给线程,即真正在处理机上运行的是线程。
- 划分尺度:线程更小,所以多线程程序并发性更高。
- 地址空间:进程拥有独立的地址空间,同一进程内多个线程共享其资源。
- 拥有资源:线程只有少量资源(TCB、PC、少量R和变量等)
- 执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
- 系统开销:线程开销小,同步和通信较简单
线程控制块TCP
- 系统为每个线程配置一个线程控制块TCB
- TCB记录所有用于控制和管理线程的信息
- 线程D、线程状态、优先级、信号屏蔽
- 一组寄存器:PC,PSW通用R
- 线程专有存储区:线程切换时保存现场信息及统计信息
- 堆栈指针:保存过程调用的形式参数及局部变量
第三章
处理机调度与死锁
处理机调度层次(三个层次)
高级调度
- 即作业调度(长程调度).调度对象:作业
- 主要功能:根据某种算法,决定将外存上处于后备队列中的哪几个作业调入内存,为它们创建进程、分配必要资源,并将它们放入就绪队列
低级调度
- 进程调度(短程调度).调度对象:进程
- 主要功能:根据某种算法,决定就绪队列中的哪个进程应获得处理机,并由分派程序将处理机分配给被选中的进程
中级调度
- 又称内存调度或中程调度
- 主要目的:挺高内存利用率和系统的吞吐量
- 主要功能:把那些暂时不能运行的进程,调至外存等待,此时进程的状态称为就绪驻外存状态(或挂起状态)。当它们具备运行条件且内存又稍有空闲时,由中级调度来决定,把外存上的那些已具备运行条件的就绪进程重新调入内存,并修改其状态为就绪状态,挂在就绪队列上等待
调度算法评价指标
CPU利用率
- 利用率=忙碌时间/总时间
系统吞吐量
- 系统吞吐量=总共完成了多少道作业/总共花了多少时间
周转时间(记)
- 周转时间=作业完成时间-作业提交时间
- 平均周转时间=各周转时间之和/作业数
- 带权周转时间=作业周转时间/作业实际运行的时间
- 平均带权周转时间=各作业带权周转时间之和/作业数
等待时间
- 等待被服务的时间之和
响应时间(记)
- 用户提交请求到首次产生响应所用的时间
处理机调度方式及算法
- 选择调度方式和算法取决于OS类型及设计目标
- 批处理系统、分时系统、实时系统采用不同调度方式和算法
处理机调度算法的共同目标
资源利用率:如处理机利用率
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhfhIosR-1678504844270)(.\image-20221208185716436.png)]
公平性:各进程都获得合理的CPU时间
平衡性:调度算法应尽可能使各种资源处于忙碌状态
策略强制执行:制订的策略必须予以准确地执行
处理机调度的准则
- CPU利用率:CPU是计算机系统中最重要和昂贵的资源之一,所以应尽可能使CPU 保持“忙”状态,使这一资源利用率最髙。
- 系统吞吐量:表示单位时间内CPU完成作业的数量。长作业需要消耗较长的处理机时间,因此会降低系统的吞吐量。而对于短作业,它们所需要消耗的处理机时间较短,因此能提高系统的吞吐量。调度算法和方式的不同,也会对系统的吞吐量产生较大的影响。
- 周转时间:是指从作业提交到作业完成所经历的时间,包括作业等待、在就绪队列中排队、在处迤机上运行以及进行输入/输出操作所花费时间的总和
批处理系统的目标
- 平均周转时间短
- 系统吞吐量高
- 处理机利用率高
分时系统的目标
- 响应时间快
- 均衡性
实时系统的目标
- 截止时间的保证
- 可预测性
作业调度(里面为非抢占式)
作业
- 用户提交给系统的一项相对独立的任务
- 作业控制块:JCB
- 作业步:对作业进行处理的相对独立的一个步骤,一个作业由 多个作业步组成。如编译、链接、运行、打印结果
作业运行的三个阶段和状态
- 收容阶段;后备状态 创建JCB,放入后备队列
- 运行阶段:运行状态 从进入就绪状态到运行结束前
- 完成阶段:完成状态 作业完成或者发生异常时
作业调度的主要任务
- 根据JCB信息,检查系统资源能否满足作业需求
- 按照调度算法,从外存后备队列中选取某些作业调入内存,并为它们创建进程、分配必要的资源
- 将新创建的进程排在就绪队列上等待进程调度
先来先服务(FCFS)调度算法
FCFS是最简单的调度算法
优点:公平,非常简单
缺点:对短作业来说用户体验不好,对长作业有利,对短作业不利
既可用于作业调度,也可用于进程调度
按照作业到达的先后次序来进行调度,它优先考虑等待时间最长的作业
FCFS很少作为主调度算法,通常与其它算法相结合
案例
进程 到达时间 运行时间 P1 0 7 P2 2 4 P3 4 1 P4 5 4 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6QmXEOQ2-1678504844271)(.\image-20221208192040528.png)]
周转时间 = 完成时间 - 到达时间
P1 = 7-0 = 7;P2 = 11-2 = 9;P3 = 12-4 = 8;P4 = 16-5 = 11
带权周转时间 = 周转时间 / 运行时间
P1 = 7/7 = 1;P2 = 9/4 = 2.25;P3 = 8/1 = 8;P4 = 11/4 = 2.75
等待时间 = 周转时间 - 运行时间(此例题进程到达后要么等待要么运行)
P1 = 7-7 = 0;P2 = 9-4 = 5;P3 = 8-1 = 7;P4 = 11-4 = 7
平均周转时间 = (7+9+8+11)/4 = 8.75
平均带权周转时间 = (1+2.25+8+2.75)/4 = 3.5
平均等待时间 = (0+5+7+7)/4 = 4.75
短作业优先(SJF)算法
SJF算法以作业的长短来计算优先级,作业越短,优先级越高
优点:“最短的”平均等待时间,平均周转时间
- 等待时间=周转时间-运行时间
作业长短是以作业所要求的运行时间来衡量
SJF算法可以分别用于作业调度和进程调度
SJF有利用于提高系统吞吐量
缺点
- 必须预知作业的运行时间
- 对长作业非常不利,完全忽视作业等待时间,有饥饿现象
- 采用SF算法时无法实现人机交互
- 完全未考虑作业的紧迫程度,不能保证紧迫性作业及时处理
案例
进程 到达时间 运行时间 P1 0 7 P2 2 4 P3 4 1 P4 5 4 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8bXHvLQg-1678504844272)(.\image-20221208192452428.png)]
周转时间 = 完成时间 - 到达时间
P1 = 7-0 = 7;P3 = 8-4 = 4;P2 = 12-2 = 10;P4 = 16-5 = 11
带权周转时间 = 周转时间 / 运行时间
P1 = 7/7 = 1;P3 = 4/1 = 4;P2 = 10/4 = 2.5;P4 = 11/4 = 2.75
等待时间 = 周转时间 - 运行时间(此例题进程到达后要么等待要么运行)
P1 = 7-7 = 0;P3 = 4-1 = 3;P2 = 10-4 = 6;P4 = 11-4 = 7
平均周转时间 = (7+4+10+11)/4 = 8
平均带权周转时间 = (1+4+2.5+2.75)/4 = 2.56
平均等待时间 = (0+3+6+7)/4 = 4
优先级调度算法(PSA)
对于FCFS,作业等待时间就是优先级;对于SJF,作业长短就是优先级,上述两种优先级都不能反映作业的紧迫程度
优点:用优先级区分紧急程度、重要程度,适用于实时操作系统。可灵活地调整对各作业/进程的偏好程度
缺点:可能会产生饥饿
根据作业紧迫程序,由外部赋予作业优先级
PSA根据作业优先级进行调度
类型
- 静态优先级:创建进程时确定,之后一直不变
- 动态优先级:创建进程时有一个初始值,之后会根据情况动态地调整优先级
PSA可用于作业调度和进程调度
案例
进程 到达时间 运行时间 优先级 P1 0 7 1 P2 2 4 2 P3 4 1 3 P4 5 4 2 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-loi8cgnX-1678504844272)(.\image-20221208193344079.png)]
0时刻(P1):只有P1到达,P1上处理机。
2时刻(P2):P2到达就绪队列,优先级比P1更高,发生抢占。P1回到就绪队列,P2上处理机。
4时刻(P1、P3):P3到达,优先级比P2更高,P2回到就绪队列,P3抢占处理机。
5时刻(P1、P2、P4):P3完成,主动释放处理机,同时,P4也到达,由于P2比P4更先进入就绪队列,因此选择P2上处理机
7时刻(P1P4):P2完成,就绪队列只剩P1、P4,P4上处理机。11时刻(P1):P4完成,P1上处理机
16时刻():P1完成,所有进程均完成
高响应比优先调度算法(HRRN)
FCFS只考虑作业等待时间,忽视作业运行时间;SJF只考虑作业运行时间,忽视等待时间
高响应比优先调度算法既考虑作业等待时间,又考虑作业运行时间
既照顾短作业,又不致使长作业等待时间过长
采用动态优先级,随着等待时间增加,优先级提高
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nKvCjRSv-1678504844273)(.\image-20221208193540732.png)]
作业等待时间与服务时间之和称为系统对该作业的响应时间
作业优先级相当于作业响应比Rp
HRRN优先调度响应比Rp高的作业
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FBkZEXfQ-1678504844274)(.\image-20221208193718019.png)]
案例
进程 到达时间 运行时间 P1 0 7 P2 2 4 P3 4 1 P4 5 4 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uiIgRMpU-1678504844274)(.\image-20221208194223028.png)]
0时刻:P1到达就绪队列,P1占用CPU
7时刻:P1主动放弃CPU,就绪队列有P2(响应比=(5+4)/4=2.25)、P3((3+1)/1=3)、P4((2+4)/4=1.5)
8时刻:P3完成,P2(2.5)、P4(1.75)
12时刻:P2完成,就绪队列只剩P4
进程调度
进程调度的任务
- 保存当前进程现场信息
- 按某种算法选取新进程
- 把处理器分配给进程
进程调度机制
- 排队器:就绪进程构成一个或多个队列
- 分派器
- 上下文切换器:两次切换
非抢占式调度
- 不会被时钟中断或其它任何原因抢占,早期OS采用
- 有局限性,无法满足交互式及实时性需求
- 引起调度因素
- 运行完毕,或出现错误
- 因IO请求暂停
- 进行通信或同步时执行某些原语,如block
- 特点:简单、开销小,适合批处理OS,不能用于实时和分时系统
抢占式调度
- 允许调度程序根据某种原则调度新进程执行
- 现代OS广泛采用:
- 批处理:防止长期占用CPU
- 分时:实现人机交互
- 实时:满足实时任务需求
- 复杂,开销大
- 抢占原则
- 优先权原则:高抢占低
- 短进程优先:短抢占长
- 时间片原则:时间片完抢占
轮转调度算法(RR)
- 原理:在简单的轮转算法中,系统将所有的就绪进程按先来先服务(即FIFO)规则排成一个队列,将CPU分配给队首进程,且规定每个进程最多允许运行一个时间片;若时间片使用完进程还没有结束,则被加入就绪FIFO队列队尾,并把CPU交给下一个进程.
- 分时系统常采用RR,非常公平,毫杪级时间片
- 程度切换时机:
- 进程完成
- 时间片用完
- 进程IO
时间片大小确定
- 时间片大小极大影响系统性能
- 小时间片有利于短作业;太小则调度频繁,开销大
- 时间片长无法满足短作业和交互式需求;太长退化为FCFS
- 以略大于一次典型交互时间为准,大多数进程在一个时间片完成
不同时间片下进程周转时间
- q=1
- 0->A,A-1,1->B,B-1,2->C,C-1,3->D,D-1,4->E,E-1,5->A,A-1,6->B,B-1,7->C,C-1,8->D,D-1
- D完成(9)
- 9->E,E-1,10->A,A-1,11->B,B-1
- B完成(12)
- 12->C,C-1,13->E,E-1,14->A,A-1
- A完成(15)
- 15->C,C-1
- C完成(16)
- 16->E,E-1
- E完成(17)
- q=2
- 0->4,A-4
- A完成(4)
- 4->B,B-3
- B完成(7)
- 7->C,C-4
- C完成(11)
- 11->D,D-2
- D完成(13)
- 13->E,E-4
- E完成(17)
多队列调度算法(了解)
- 采用一个进程就绪队列,低级调度算法固定、单一,无法满足不同用户对进程调度策略的不同要求
- 多个进程就绪队列,不同队列有不同调度算法,不同优先级
- 针对不同用户进程提供多种调度策略
- 针对多CPU,一个CPU进程可放于单个就绪队列
- 相互合作的进行分配到不同队列以提高并行性
多级反馈队列调度算法
- 前面的算法有局限。不知进程长度时SPF和基于进程长度抢先式 调度无法使用
- 不必事先知道进程长度,较好满足各种类型进程需要
- 目前公认较好的算法
- 多级反馈队列调度算法调度机制
- 设置多个就绪队列,不同队列优先级不同,时间片不同
- 每个队列都采用FCFS算法, 最后队列采取按RR
- 按队列优先级调度,属于抢先式调度
- 案例
- 假设系统中有3个就绪队列Q1,Q2,Q3,时间片分别为2,4,8。现在有3个作业J1,J2,J3分别在时间 0 ,1,3时刻到达。而它们所需要的CPU时间分别是3,2,1个时间片。
- 时刻0: J1到达。于是进入到队列1 , 运行1个时间片 , 时间片还未到,此时J2到达。
- 时刻1: J2到达。 由于时间片仍然由J1掌控,于是等待。 J1在运行了1个时间片后,已经完成了在Q1中的2个时间片的限制,于是J1置于Q2等待被调度。现在处理机分配给J2。
- 时刻2: J1进入Q2等待调度,J2获得CPU开始运行。
- 时刻3:J3到达,由于J2的时间片未到,故J3在Q1等待调度,J1也在Q2等待调度。
- 时刻4:J2处理完成,由于J3,J1都在等待调度,但是J3所在的队列比J1所在的队列的优先级要高,于是J3被调度,J1继续在Q2等待。
- 时刻5:J3经过1个时间片,完成。
- 时刻6:由于Q1已经空闲,于是开始调度Q2中的作业,则J1得到处理器开始运行。
- 时刻7:J1再经过一个时间片,完成了任务。于是整个调度过程结束。
-
- 算法性能
- 终端型用户
- 短批处理作业用户
- 长批处理作业用户
基于公平原则调度算法(了解)
- 前面算法只保证优先运行,不保证作业(进程)占用的处理机时 间,未考虑调度公平性
- 基于公平原则调度算法强调公平性,包括:
- 保证调度算法:保证进程分配处理机的公平性
- 公平分享调度算法 :保证用户分配处理机的公平性
- 保证调度算法分配给每个进程相同的处理机时间
- 若各用户进程数不同,则对用户不公平
- 公平分享调度算法保证用户获得公平调度时间
实时调度
实时调度用于实时系统
- 硬实时任务HRT
- 软实时任务SRT
基本条件
提供必要的信息
- 就绪时间:某任务成为就绪状态的起始时间
- 开始截止时间和完成截止时间
- 处理时间:任务从开始执行,到完成所需时间
- 资源要求:任务执行时所需资源
- 优先级:"绝对"或"相对"优先级
系统处理能力强
若RTOS处理能力不强,可能致使实时任务不能及时处理
假定有m个周期性HRT,每个HRT处理时间为Ci,周期时间为Pi
则在单处理机可调度条件:
单处理机系统须增强CPU能力,减少每个任务处理时间
采用多处理机系统,CPU数为N应满足:
采用抢占式调度
- 含有HRT任务R5广泛采用抢占机制,才可满足截止时间要求
- 抢占式调度机制比较复杂
- 小型RTOS也可采非抢占式调度,条件:
- 任务尽量小
- 及时阻塞自己.释放CPU
具有快速切换机制
- RTOS中应具有快速切换机制,使HRT任务快速切换
- 应具有以下能力
- 对中断的快速响应能力:中断及时响应&处理时间短
- 快速的任务分派能力:每个运行单位尽量小,减少任务切换时间开销
实时调度算法分类
根据实时任务性质分类
- 硬实时调度算法
- 软实时调度算法
按调度方式分类
- 非抢占调度算法
- 抢占调度算法
非抢占式调度算法
- 非抢占式轮转调度算法
- 非抢占式优先调度算法
抢占式调度算法
- 基于时钟中断抢占式优先级调度篇法
- 特点:时钟中断时才抢占,较好响应时间,可适用大多数RTOS
- 立即抢占优先级调度算法
- 特点:要求快速中断响应;出现中断且非临界区则抢占;响应快速
实时调度举例
- 前提实时进程比当前进程优先级高
-
- a:实时进程进入队列末尾,
- b.实时进程进入当前执行进程的下一个位置
- c.实时进程等到在实时中断到来时抢占CPU,
- d.实时进程之间直接抢占当前进程并立刻执行
最早截止时间优先EDF算法
- 根据任务截止时间确定优先级,越早越高
- 最早截止时间任务排队首
- 总是选择就绪队列队首任务调度
- 可用于抢占式调度或非抢占式调度
- 非抢占式调度
-
- 任务1最先到达最先开始执行
- 任务1执行过程中任务2、任务3到达,由于任务3截止时间更早,其优先级愈高,所以执行完任务1后执行任务3
- 任务3执行过程中任务4到达,由于任务4截止时间更早优先级愈高,任务3执行完后执行任务4,
- 最后执行任务2
- 抢占式调度
-
- 周期任务A,周期时间20ms,处理时间10ms
- 周期任务B,周期时间50ms,处理时间25ms
- 为了说明通常的优先级调度不能适用于实时系统,该图增加了固定优先级调度的第二行和第三行
- 第二行中
- 固定A,B优先级,且优先级A>B;
- 先执行A1,A1执行完后执行B1;
- B1执行了10ms后被A2抢占;
- A2执行完后继续执行B2;
- B2执行10ms后被A3抢占;
- A3执行完后已经到达B2的截止时间了,但B2总共执行了20ms,很明显低于所需处理时间25ms。
- 第三行中
- 固定A,B优先级,且优先级B>A;
- 先执行B1,B1执行完后已经过了A1的截止时间,可知A1根本就没能执行到。
- 第四行中
- A1截止时间早于B1截止时间,先执行A1;
- A1执行完执行B1,B1执行10ms后A2到达;
- A2截止时间早于B1截止时间,先执行A2;
- A2执行完执行B1,B1执行10ms后A3到达;
- B1截止时间早于A3截止时间,继续执行B3;
- 以此类推,每个任务有序无错过进行,能满足系统的要求。
最低松弛度优先LLF算法
- 根据任务的紧急(或松弛)程度确定优先级
- 紧急程度越高,则优先级越高
- 按松弛度排序的就绪队列,松弛度低任务排在前,从队首选择
- 主要用于可抢占式调度
- 任务最迟开始时间:任务必须完寸间一运行时间
- 松弛度(紧迫度)=任务最迟开始时间与当前时间的差=任务必须完成时间.运行时间.当前时间
- 假如在一个实时系统中,有两个周期性实时任务A和B,任务A要求每 20 ms执行一次,执行时间为 10 ms;任务B只要求每50 ms执行一次,执行时间为 25 ms
- 案例
- 周期性任务A,要求每20ms执行一次,执行时间为10ms;
- 周期性任务B,要求每50ms执行一次,执行时间为25ms;
- t=0s时,A1的松弛度=20ms-10ms-0ms=10ms,B1的松弛度=50ms-25ms-0=25ms,先执行A1;
- A1执行完后,t = 10ms ,B1的松弛度=50ms-25ms-10ms=15ms,A2的松弛度=40ms-10ms-10ms=20ms,执行B1;
- B1执行20ms后,t = 30ms, B1的松弛度=50ms-5ms-30ms=15ms,A2的松弛度=40ms-10ms-30ms=0ms,继续执行A2;
- A2执行10ms后,t = 40ms,A3的松弛度= 60-10-40 = 10,B1 = 50-5-40 = 5ms ,所以执行B1 接下来以此类推
死锁(重)
可重用性资源
- 可供用户重复使用多次的资源
- 一次只能分配给一个进程使用,不允许多个进程共享
- 使用方式:请求资源;使用资源;释放资源
- 资源数目相对固定,进程运行期间既不能创建也不能删除
- 通过系统调用请求和释放
- 系统大多数资源属于可重用性资源
可消耗性资源(临时性资源)
- 可消耗性资源又时性资源
- 在进程运行期回申进逞动态地创建和消耗,数目不断变化
- 可消耗性资源通韋由生产者进程创建,由消费者进程消耗
- 例如进程通信中的消息
可抢占性资源和不可抢占资源
- 可抢占资源
- 进程获得这类资源后可以冉被其它进程或系统抢占
- 例如cpu调度,内存对换
- 不会引起死锁
- 不可抢占性资源
- 一旦分配给某进程就不能将它强行收回
- 例如:打印机、记录机、磁带机
资源分配图
- 图示进程对资源的访问情况
- 方块代表资源,方块内数字
代表表资源数量- 圆圈代表进程
- 从进程指向资源的箭头表示请求资源
- 从资源指向进程的箭示已分配资源
- 案例(化简资源分配图)
- 方法步骤
- 第一步:先看系统还剩下多少资源没分配,再看有哪些进程是不阻塞(“不阻塞”即:系统有足够的空闲资源分配给它)的
- 第二步:把不阻塞的进程的所有边都去掉,形成一个孤立的点,再把系统分配给这个进程的资源回收回来
- 第三步:看剩下的进程有哪些是不阻塞的,然后又把它们逐个变成孤立的点。
- 第四步:最后,所有的资源和进程都变成孤立的点。这样的图就叫做“可完全简化”。
- 第一步:先看R1资源,它有三个箭头是向外的,因此它一共给进程分配了3个资源,此时,R1没有空闲的资源剩余。 - 第二步:再看R2资源,它有一个箭头是向外的,因此它一共给进程分配了1个资源,此时,R2还剩余一个空闲的资源没分配。 - 第三步:看完资源,再来看进程,先看进程P2,它只申请一个R1资源,但此时R1资源已经用光了,所以,进程P2进入阻塞状态,因此,进程P2暂时不能化成孤立的点。 - 第四步:再看进程P1,它只申请一个R2资源,此时,系统还剩余一个R2资源没分配,因此,可以满足P1的申请。这样,进程P1便得到了它的全部所需资源,所以它不会进入阻塞状态,可以一直运行,等它运行完后,我们再把它的所有的资源释放。相当于:可以把P1的所有的边去掉,变成一个孤立的点,如下图所示: - 
- 第五步:进程P1运行完后,释放其所占有的资源(2个R1资源和1个R2资源),系统回收这些资源后,空闲的资源便变成2个R1资源和1个R2资源,由于进程P2一直在申请一个R1资源,所以此时,系统能满足它的申请。这样,进程P2便得到了它的全部所需资源,所以它不会进入阻塞状态,可以一直运行,等它运行完后,我们再把它的所有的资源释放。相当于:可以把P2的所有的边都去掉,化成一个孤立的点,变成下图: - 
- 由于这个资源分配图可完全简化,因此,不会产生死锁。 而如果资源分配图中的点,最终不能够化成孤立的点,则进程资源图不能够完全简化,从而会发生死锁。
死锁定义
- 进程中的每一个进程都在等待仅由该组织进程中的其它进程才能引发的事件,那么该组进程是死锁的。
产生原因
- 产生死锁的原因
- 竞争资源
- 竞争不可抢占性资源引起死锁
- 竞争可消耗资源引起死锁
- 进程间推进顺序非法
- 进程运行中对资源申请和 - 释放不当也会引起死锁 - 打印机R1,磁带机R2使用R1,R2 - 顺序1,2,3不会死锁 - 顺序4进入不安全区域D
产生死锁的四个必要条件
- 互斥条件
- 请求和保持条件
- 不可抢占条件
- 循环等待条件
- 以上任一个条件不成立,死锁就不会发生
处理死锁的方法
- 预防死锁:事先预防破坏四个要条件。简单,广泛采用
- 避免死锁:事先预防,资源分配时防止进入不安全状态
- 检测死锁:事后检测再解除死锁
- 解除死锁:例如撤消进程
预防死锁
- 破坏产生死锁四个必要要条件中的一个或几个
- 互斥条件是非共享设备所必须的,必须保证
- 主要是破坏产生死锁的后三个条件
- 请求和保持条件
- 不可抢占条件
- 循环等待条件
破坏请求和保持
- 当进程在请求资源时,它不能持有不可抢占资源
- 方式一
- 所有进程在开始运行前,必须一次性地申请其在整个运行过程中的全部资源
- 特点:简单、易行、安全、资源利用率低、有进程饥饿问题
- 方式二
- 获得初期所需资源后开始运行。运行中可逐步申请资源,但申请新资源时要释放旧资源
- 特点:提高资源利用率,减少饥饿机率
破坏不可抢占条件
- 进程提出新资源请求而不能满足时必须释放已经保持的所有资源,待以后需要时再重新申请
- 进程已占有的资源会被暂时地释放,或者说是被抢占
- 特点:实现复杂、代价大;反复申请释放,延长进程周转时间、增加系统开销、降低系统吞吐量
- 但是被迫释放可能会影响前期成果
破坏循环等待条件
- 对系统所有资源类型进行线性排序,并赋予不同的序号
- 进程序号递增的顺序请求资源,多个同类资源要一起请求
- 申请低序号N资源方法:先释放>=N的资源,再申请资源N
- 通常按照进程使用资源顺序确定序号
- 特点:资源利用率高、吞吐量大;难增加新设备;进程资源使用顺序与系统规定不同时造成资源浪费;限制用户自主编程
死锁避免思想
- 避免死锁属于事先预防策略
- 在资源动态分配过程防止系统进入不安全状态,以僻免发生死锁
- 拖加的限制条件较弱,系统性能较好
- 目前常此方法来避免发生死锁
安全状态与不安全状态
- 系统处于安全状态时可避免发生死锁
- 系统处于不安全状态时则可能发生死锁
- 安全状态一定不会死锁,不安全状态可能死锁
- 避免死锁的实质:在资源分配时使系统不进入不安全状态
安全状态
指系统能找到某种进程推进顺序(P1,P2,Pn)为每个资源分配所需的最大资源,使每个进程都可顺序完成
安全序列
找到进程推进顺序(P1,P2…Pn)
避免死锁实质就是使系统一直处于安全状态
如果系统处于安全状态,就一定不会发生死锁;如果系统处于不安全状态,就可能会发生死锁。
案例
银行家死锁避免算法
算法思想
- 新进程进入系统须声明对每种资源的最大需求量
- 进程申请资源时先确定是否有足够资源
- 若足够再判断分配后是否是安全状态
- 若安全则分配,否则让进程等待
数据结构
- 可利用资源向量Available(含有m个元素的数组)
- 可利用资源的数量,初值为系统类资源总数量。Availabe[j]=K,表示系统中现有Rj类资源K个。
- 最大需求矩阵Max(n×m的矩阵)
- 每个进程对每类资源的最大需求数量。Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。(i表示进程,j表示资源)
- 分配矩阵Allocation(n×m的矩阵)
- 系统中每一类资源当前已分配给每一进程的资源数.Allocation[i,j]=K 表示进程i当前已分得Rj类资源的数目为K。
- 需求矩阵Need(n×m的矩阵)
- 每一个进程尚需的各类资源数.Need[i,j]=K 表示进程i还需要Rj类资源K个,方能完成其任务
算法流程
如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:
如果Requesti[j]<=Need[i,j],转步骤(2);否则出错。
如果Requesti[j]<=Available[j],转步骤(3);否则,表示尚无足够资源,Pi须等待。
系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]= Available[j]-Requesti[j]; Allocation[i,j]=Allocation[i,j]+ Requesti[j]; Need[i,j]=Need[i,j]- Requesti[j];
系统执行安全性检查,若安全,则正式分配;否则,本次的试探分配作废,恢复原本的资源分配状态,让进程Pi等待。
安全性算法
- 设置两个向量:
- 工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work∶=Available;
- Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true
- 从进程集合中找到一个能满足下述条件的进程:
- ① Finish[i]=false; ② Need[i,j]≤Work[j]; 若找到, 执行步骤4, 否则,执行步骤5。
- 当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
- Work[j]=Work[i]+Allocation[i,j];
- Finish[i]=true;
- go to step 3;
- 如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。
银行家算法举例
T0时刻资源分配情况
Max Allocation Need Available A B C A B C A B C A B C P0 7 5 3 0 1 0 7 4 3 3 3 2 P1 3 2 2 2 0 0 1 2 2 P2 9 0 2 3 0 2 6 0 0 P3 2 2 2 2 1 1 0 1 1 P4 4 3 3 0 0 2 4 3 1 T0时刻存在安全序列{P1,P3,P4,P2,P0}
Work Need Allocation Work+Allocation Finish A B C A B C A B C A B C P1 3 3 2 1 2 2 2 0 0 5 3 2 True P3 5 3 2 0 1 1 2 1 1 7 4 3 True P4 7 4 3 4 3 1 0 0 2 7 4 5 True P2 7 4 5 6 0 0 3 0 2 10 4 7 True P0 10 4 7 7 4 3 0 1 0 10 5 7 True P1请求资源:P1发出请求向量Request1(1,0,2),系统按银行家算法进行检查:
Request1(1, 0, 2)≤Need1(1, 2, 2)
Request1(1, 0, 2)≤Available1(3, 3, 2)
系统先假定可为P1分配资源,并修改Available, Allocation1和Need1向量,由此形成的资源变化情况如图 的圆括号所示。
Max Allocation Need Available A B C A B C A B C A B C P0 7 5 3 0 1 0 7 4 3 3 3 2(2 3 0) P1 3 2 2 2 0 0(3 0 2) 1 2 2(0 2 2) P2 9 0 2 3 0 2 6 0 0 P3 2 2 2 2 1 1 0 1 1 P4 4 3 3 0 0 2 4 3 1 再利用安全性算法检查此时系统是否安全。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dQHmhbjT-1678504844284)(.\image-20221211155941686.png)]
P4请求资源:P4发出请求向量Request4(3,3,0),系统按银行家算法进行检查:
① Request4(3, 3, 0)≤Need4(4, 3, 1);
② Request4(3, 3, 0) < Available(2, 3, 0),让P4等待。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVi46Pkd-1678504844285)(.\image-20221211160156184.png)]
P0请求资源:P0发出请求向量Requst0(0,2,0),系统按银行家算法进行检查:
① Request0(0, 2, 0)≤Need0(7, 4, 3);
② Request0(0, 2, 0)≤Available(2, 3, 0);
③ 系统暂时先假定可为P0分配资源,并修改有关数据,
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ko9MwldS-1678504844285)(.\image-20221211160306029.png)]
- 再进行安全性检查:可用资源Available(),1,0)不能满足任何进
程的需要,故系统进入不安全状态,拒绝分配资源- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZHHONbP8-1678504844285)(.\image-20221211160519786.png)]
也就是在每次请求资源时要先进行银行家算法和安全性算法判断是否有安全序列,通过了开始真正分配
死锁的检测和解除
- 系统不采取死锁预防措施,也未配有死锁避免算法
- 此时系统应当提供两个算法:
- 死锁检测算法;判断系统是否发生死锁
- 死锁解除算法:发生死锁时,利用该算法使系统脱离死锁状态
死锁定理
- 利用资源分配图化简方法来检测系统是否为死锁状态
- 在图找出一个既不阻塞又非独立的进程结点,消去Pi的请求边和分配边,使之成为孤立
- 经过简化若能消去图中所有的边,使所有的进程结点都成为孤立
结点,则称该图是可完全简化,没有死锁;若不能完全简化,则发生死锁
死锁检测步骤
- 可利用资源向量Available,它表示了m类资源中每一类资源的可用数目。
- 把不占用资源的进程(向量Allocation∶=0)记入L表中, 即Li∪L。
- 从进程集合中找到一个Requesti≤Work的进程,做如下处理:① 将其资源分配图简化,释放出资源,增加工作向量Work∶=Work+Allocationi。 ② 将它记入L表中。
- 若不能把所有进程都记入L表中, 便表明系统状态S的资源分配图是不可完全简化的。 因此,该系统状态将发生死锁。
第四章
存储器的层次结构
用户对存储器的要求
- 速度快,与CPU速度相匹配
- 容量大
- 便宜
以上三个条件不能同时满足,全部采用层次结构存储器
内存扩充
- 覆盖技术
- 交换技术
- 虚拟存储技术
存储器的多层结构
- 通用计算机存储层次至少三级:R(CPU寄存器),M(主存),S(辅存)
- 高级计算机更多层次:R,高速缓存,M,磁盘缓存,固定磁盘,可移动存储介质等6层
- 层次越高(越靠近CPU),存储介质的访问速度越快,价格也越高,相对所配置的存储容量也越小
可执行存储器
存储器和主存储器被称为可执行存储器
- 其访问机制以及访问速度与辅存不同,赋存涉及中断,设备驱动等,非常慢
- OS的存储管理负责可执行存储器的分配,回收,数据移动等管理
- OS的设备和文件管理实现对辅存管理
主存储器与寄存器
主存储器简称内存或主存
- 主存保存进程运行时的程序和数据,也称可执行存储器
- 程序执行时M和R互相传输数据,读/写
- 主存速度远低于CPU,所有引入R和cache
寄存器
- 寄存器与处理机速度相同
- 访问寄存器速度最快,能与CPU协调工作
- 价格昂贵,容量小,几个到几百个
- R长度:8位,16位,32位
- 通用R和专用R
高速缓存cache
- 介于寄存器和M之间
- 访问速度快于M
- 主要用于备份主存1中较常用的数据,减少CPU访问M次数,提高程序执行速度
- 容量远大于寄存器
- 二级或多级cache
- 程序局部性原理(时间/空间)
磁盘缓存
- 磁盘I/O速度远低于主存访问速度
- 为缓和两者速度不匹配,而设置磁盘缓存
- 暂时存放频繁使用的部分磁盘数据和信息,以减少访问磁盘次数
- 磁盘缓存不是一种实际存在的存储器
- 利用主存的部分存储空间暂时存放从磁盘中的I/O的信息
- 数据在文件(磁盘)-磁盘缓存-主存-cache-R之间的传输
程序的装入与链接
- 编译:等到目标模块
- 链接:链接程序生成完整装入模块
- 装入程序将装入模块装入内存
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ULljBgxA-1678504844288)(.\IMG_20230205_093400.jpg)]
程序的装入
绝对装入方式(记)
- 早期单道程序采用绝对装入方式,DOS
- 编译时产生绝对地址
- 只适用于单道程序环境
- 用户程序编译后产生绝对地址(物理地址)的目标代码
- 程序装入位置固定
- 程序相对地址(逻辑地址)与实际内存地址相同,无需重新定位
可重定位装入方式(静态重定位)(记)
- 多道环境中目标模块起始地址都从0开始,其他地址都相对于起始地址计算
- 逻辑地址与物理地址不同,采用可重定位装入的方式
- 装入时将逻辑地址转化为物理地址
- 根据模块装入内存的起始地址修改模块内其他逻辑地址
动态运行时装入方式(记)
- 装入时逻辑地址不变,装入内存的模块全采用逻辑地址
- 运行时才地址转换
- 运行时将逻辑地址转化为物理地址,需要设置重定位寄存器
- 需要硬件重定位寄存器支持
- 允许程序在内存中移动位置
链接
- 将多个目标模块以及库函数装配成一个完整的装入模块
- 链接方式
- 静态链接
- 装入时动态链接
- 运行时动态链接
静态链接(记)
- 事先链接,程序运行前链接
- 运行前将各目标模块及所需库函数链接成一个完整的装配模块
- 链接时要解决的问题:
- 对相对地址进行修改
- 变换外部调用符号
- 静态链接生成完整装入模块,即可执行文件,以后不再拆开,可以直接装入内存运行
- .lib,.a
装入时动态链接方式(记)
- 目标模块在装入内存时采用边装入边链接的链接方式
- 在装入目标模块、若发生外部模块调用事件,由裝入程序去找该外部目标模块,并将其装入内存,并修改模块内相对地址
- 优点
- 使于修改和更新,修改一个模块不影响其它模块
- 便于实现对目标模块的共享,将一个目标模块链接到几个应用模块上
运行时动态链接方式(记)
- 静态链接和装入时动态链接低效、浪费内存。例如错误处理
- 运行时动态链接.对某些模块的链接推迟到调用时才进行
- 执行过程中未调用的模块不会链接,不会被调入内存
- 优点.加快装入过程,节省内存
- .all,.so
连续分配存储管理方式
单一连续分配
- 用于单道程序环境
- 最简单的一种存储管理方式,但只能用于单用户、单任务的OS中
- 内存分为系统区和用户区两部分
- 系统区(低址部分)给os使用
- 用户区仅装入一道用户程序,程序独占整个用户空间
- 早期cp/M,MS-DOS,RT11等,不设存储保护机制
- 产生内部碎片
固定分区分配
- 最早用多道系统储管理方式,如旧M360MFT系统
- 用户空间划分若干固定大小区域,每个分区装入一道作业
- 分区划分方法:
- 分区大小相等。方便、实用、但缺乏灵活
- 分区大小不等。根据用户需要划分,分配灵活
- 易造成存储空间浪浪费
- 通过对“分区使用表”的改写,来实现主存的分配与回收。作业在执行时,不会改变存储区域,所以采用静态地址重定位方式。此方法易于实现,系统开销小
- 产生内部碎片
动态分区分配(重点)
- 根据进程实际需要动态分配内存
- 涉及到有关数据结构、分区分配算法以及分区分配和回收操作
- 装入新作业时,按照一定的分配筒法,从空闲分区表或空闲分区链中选出一分区分配,对系统性能影响很大。
- 两类分配算法
- 顺序式搜索算法
- 索引式搜索算法
- 数据结构:空闲分区表;空闲分区链
1.
动态分区内存回收
- 释放内存时,根据回收区首址,从空闲区链(表)找到插入点:
- 回收区与插入点的前一个空闲分区F1相邻接
- 回收分区与插入点的后一空闲分区F2相邻接
- 回收区同时与插入点的前、后两个分区邻接
- 回收区既不与F1邻接,又不F2邻接,为回收区单独建立一个新表项
- 回收操作
基于顺序搜索动态分区分配算法(重点)
- 系统空闲分区构成一个链
- 依次搜索空闲分区链上分的分区,找到大小满足需要的分区
首次适应算法
- FF算法要求空闲分区链以地址递增次序链接
- 从链首开始顺序查找,直至找到大小满足要求的一个空闲分区
- 从分区划出空间,余下的空闲分区仍留在空闲链中
- 若找不到,则内存配失败
- 特点
- 优先使用低址内存,保留高址大空闲区
- 容易产生碎片
- 从链首找,增加直找开销
循环首次适应算法(NF算法)
- 为避免低址部分留下许多很小的空闲分区以及减少查找可用空闲分区的开销
- NF算法从上次找到的空闲分区的下个分区开始查找
- 应设置一个起始查找指针,采用循环查找法
- 特点
- 碎片减少
- 缩短查找时间
- 缺乏大空闲分区
最佳适应(BF)算法
- 总是分配满足要求目最小的空闲分区,避免"大材小用"
- 要求空闲分区按容量从小到大排序
- 第一个找到的分区即是最佳
- 效果并非最佳,太多无用碎片
最坏适应(WF)算法
- 总是挑选最大的空闲区分配
- 要求空闲区按照大小从大到小排序
- 特点:
- 碎片少,对中小作业有利
- 查找效率高
- 缺乏大空间分区
基于索引搜索的动态分区分配算法
- 基于顺序搜索分配算法适用于不太大的系统
- 大中型系统采用基于索引的动态分区算法,分三种:
- 快速适应算法
- 哈希算法
- 伙伴系统
快速适应算法
- 又称分类搜索法,将空闲分区根据容量大小分类
- 系统有多个空闲分区链,每类相同容量分区单独设立一个分区链
- 内存中设立一张管理索引表,每一个索引表项对应一个分区链,并记录分区链表头指针
- 按照进程常用空间大小进行空闲分区分
- 分配方法
- 找满足要求的最小分区链
- 取第一块分配
- 优点
- 不分割分区,无碎片并保留大分区
- 查找效率高
- 缺点
- 归还分区复杂,系统开销大
- 以进程为单位,一个分区只属于一个进程,有浪费。
伙伴系统
- 规定所有分区大小均为2的k次幂(1<=k<=m,总内存2m次方
- 开始运行时整个内存是一个2m次方的空闲分区
- 相同大小空闲区单独设立一个双向链表,共有k个空闲分区链表
- 请求分配2(i-1)次方<=n<=2i次方,查找2的i,2的i+1次方…,分配时可能多次分割内存
- 内存回收时可能多次合并
- 优点
- 分配回收时间性能比快速适应法差,比顺序搜索法好
- 内存使用率比快速适应法好,比顺序搜索法差
- 多处理机系统仍广泛使用
哈希算法
- 利用哈希方法快速查找的优点,add=hush(key)
- 构造以空闲分区大小为关键字的哈希表,每个表项指向对应空闲分区链表
- 根据所需空闲分区大小,通过哈希函数计算,得到哈希表项位置,从中得到相应空闲分区链表,实现最佳分配。
动态可重定位分区分配
紧凑
- 连续分配要求分配一片连续的内存空间
- 不能利用的小空闲分区称为碎片或零头
- 通过移动内存作业位置,把多个分散小空闲分区拼接大分区称为紧凑或拼接
- 每次紧凑后要对程序重定位
动态重定位
- 动态运行时装入方式,装入内存的所有地址仍是相对(逻辑)地址,运行时才转换为绝对(物理)地址
- 用硬件地址变换提高效率
- 增设重定位寄存器,存放程序(数据)在内存的起始地址
- 执行真正访问的内存地址是相对地址与重定位寄存器的和
- 紧凑时只需要用新起始地址修改重定位寄存
动态重定位分区分配算法
- 动态重定位分区分配算法与动态分区分配算法基本相同,只增加紧凑功能
- 当找到足够大空闲分区时,若所有小空闲分区容量总满足要求,则进行"紧凑"
- 无法紧凑时分配失败
对换
对换的引入
- 对换概念,为什么要对换
- 对换改善内存和CPU利用率,提高系统吞吐量
- 被广泛采用,linux有对换进程swap分区,windows也支持对换功能、
定义
- 把内存中暂时不能运行的进程或者暂时不用的程序和数据换出到外存上,以便腾出足够的内存空间,再把具备运行条件的进程或进程所要的程序和数据换入内存
对换的类型
- 每次对换都是将一定数量的程序或数据换入或换出内存
- 根据每次对换时对换的数量分为两类
- 整体对换:也叫进程对换,以进程为单位,解决内存紧张问题,广泛用于道程序系统的中级调度。(分时系统)
- 页面(分段对换):也称部分对换,以页面或分段为单位,目的**支持VM,**用于请求分页或请求分段存储管理中。
对换空间管理的主要目标
- 对换空间的管理:对换空间管理的主要标是提高进程换入、换出的速度,因此通常将对换空间设置在高速的磁盘中,并采取简单的连续分配方式。
- 具有对换功能的os磁盘空间分为文件区和对换区两部分
- 对文件区主要目标:大部分磁盘空间,存放文件目录和内容,主要目标提高磁盘存储空间利用率,采用离散分配方式
- 对对换空间管理的主要目标:存放换出的进程,主要目标提高对换速度,采用连续分配,较少考虑外存碎片
对换空间磁盘块管理的数据结构
- 为管理对换区的空闲盘块,应配置相应数据结构,记录外存对换区中空闲盘块使用情况
- 动态内存分区分配类似,采用空闲分区表或空闲分区链
- 空闲分区表应包含两项:
- 对换区首址,用盘块号表示
- 对换区大小,用盘块数表示
对换空间的分配和回收
- 对换分区采用连续分配,其分配与回收与动态分区方式类似
- 分配算法可以是首次适应筒巷、循环首次适应算法或最佳适应算法等
- 分配回收操作要根据前后对换分区使用情况进行分割或者合并
进程的换出
- 内核发现内存不足时唤醒对换进程执行换出
- 对换进程将内存中某些进程调出至对换区,腾出内存空间
- 步骤
- 选择被换出的进程:选择标准
- 首先选择阻塞或睡眠状态进程
- 有多个时选择优先级进程
- 还要考虑进程在内存驻留时间
- 若无阻塞讲程,则选低优先级就绪讲程
- 进程换出过程:只能换出非共享段
进程的换入
- 对换进程定时执行换入操作
- 找"就绪"状态已换出的进程,有多个时选择换出时间最久进程
- 对换很消耗时间。os正常运行不启动对换进程,发现经常缺页(段)中断时才启动
分页存储管理方式
碎片
- 内存碎片:指的是已经被分配出去的,但是却没有被使用的内存空间。 因为基本存储单位的限制
- 外存碎片:指的是还没有被分配的,但是由于太小或者是不连续,而导致不满足要求,所以没办法被分配的内存空间
离散式内存管理
- 连续内存分配有碎片,紧凑开销大
- 离散内存分配允许将进程分散装入到许多不相邻的内存空间
- 分类
- 分页存储管理方式
- 分段存储管理方式
- 段页式存储管理方式
分页存储管理方式(离散分配)
- 逻辑地址空间分若干页(逻辑页),物理空间分若干块(物理块),都从0编号
- 逻辑页大小=物理页大小
- 以块为单位进行分配,进程逻辑页装入不邻接多个物理块
- 页太小(页面大小为2的幂次,1kb-8kb):减少页内碎片,但页表长,占内存,影响换入换出效率
- 页太大.
- 分页管理的地址结构(INF为整除,MOD取余)
- 页表
- 分页系统允许将进程各逻辑页离散地存储在内存任一物理块
- 为每个进程建立一张页面映像表,简称页表
- 页表作用是实现逻辑页号到物理块号的映射
- 进程每个逻辑页占一个表项
- 页表项内容:逻辑页号、物理块号、存储控制字段
地址变换机构
- 地址变换机构(硬件)
- 实现逻辑地址到物理地址的转换
- 由于页内地址和物理块内地址对应,地址变换主要是逻辑页号到物理块号的变换
- 地址变换借助页表实现
- 地址变换频繁发生,采用硬件实现
- 基本地址变换机构(两次)
- 页表用寄存器实现&页表驻留内存
- 系统设置一个页表寄存器PTR,存放页表首址及页表长度
- 页表首址及页表长度存于进程PCB,运行时装入PTR
- 变换过程(重)
- 具有快表的地址变换结构(一次)
- 基本分页系统存取一个数据要两次访问内存
- 快表,联想寄存器或TLB,具有并行查找能力的特殊高速缓冲寄存器
- 快表用于缓存页表中经常访问的页表项
- 程序的局部性原理
- 命中率高的快表约损失10%速度
访问内存的有效时间
- 从发出逻辑地址访问请求到访问实际物理地址单元并取出数据,所花费总时间称为内存的有效访问时间EAT
- 设t为访问一次内存所需要的时间,则:
- 基本分页系统:EAT=t+t=2t,
- 有快表分页系统:EAT=ax入+(t+入)(1—a)+t=2t+入—txa,入为查找快表时间,a为快中率
两级及多级页表
- 当代os地址空间很大,页表占很大连续内存空间
- 页表空间采离散分配,
- 部分页表调入内存,其它部分在磁盘,需要时调入
两级页表
- 解决难找到大连续内存空间存放灾表,但页表占间问题未解决
- 将内页表分页,为页表再建立一张页表(外层页表),该页表项记录内页表的内存首地址
- 逻辑地址分为外层页号、外层页内地址、页内地址
- 两级页表地址变换实例
多级页表
- 对于32位机器采用两级页表是合适
- 对于64位机器要采用多级页表
- 多级页表把夕卜页表再分页,并装入不连续的物理空间
- 目前64位os逻辑地址空间最大为64TB:246,三级页表可行
分段存储管理方式
存储管理发展
- 以提高内存利用率为目的
- 以满足用户和程序员需要
为什么要分段式存储管理
- 分段管理更好符合程序员如下需求:
- 方便编程:照逻辑关系划分为若干个段,每个段都从0开始编址,并有自己的名字和长度,程序逻辑地址由段名(段号)和段内偏移量(段内地址)组成,方便编程,程序非常直观,可读性好。
- 信息共享:共享是以过程、函数或文件为单位,段是信息逻輯单位。按页划分不合理。
- 信息保护:信息保护也是以过程,函数或文件为单位。
- 动态增长: 数据段动态内存分配,很难进行预分配。
- 动态链接:动态链接要求以目标程序(即段)为链接单位。
分段式存储管理
- 用户地址空间划分为若干个段,每个段定义一组逻辑信息
- 每个段都有名字(段号)和长度,都从0开始编址,采用连续分配
- 程序地址空间分为多个段,各段长度不相等,程序逻辑地址由段名假号厢段内偏移量〈段内地址)组成
- 分段地址中的地址具有如下结构
段表
- 分段式存储管理中,每段分配一个连续分区
- 一个进程有多个段,各段离散地装入内存不同分区中
- 每个进程一张段映射表,简称段表,每个段占一项,记录该段在内存的首地址和段长
- 段表放于内存(或R中),用于实现地址转换
- 段式管理地址变换机构
- 系统设置一个段表寄存器,用于存放段表始址和段表长度TL
- 一次访问数据需欠访问内存
- 可用快表(联想寄存器)保存最近常用的段信息
- 进程段数远少于页数
分页与分段的主要区别
- 分页
- 页是信息物理单位,用户不可见
- 分页目的是提高内存利用率
- 页大小固定,由系统决定
- 分页是一维逻辑地址空间
- 分段
- 段是信息逻辑单位,用户可见
- 分段目的是满足用户需要
- 段长度不固定,由用户程序决定
- 分段是二维逻辑地址空间
信息共享
分页系统信息共享
- 分段系统可方便实的共享和保护
- 分页系统也能实现程序和数据共享,但远不如分段系统方便
- 分页系统要求各进程页表中共享代码的页表项指向同一个物理块
- 分段信息共享
段页式存储管理
- 分页管理以页为管理单位,提高内存利用率,减少外碎片
- 分段管理以段为管理单位,更好满足用户需要
- 段页式管理将页式与段式结合,既能解决外碎片,又方便共享、保护、可动态链接
基本原理
- 段页式系统将分段和分页原理的结合,先将用户程序分成若干个,再把每个段分成若干个页
- 地址结构由段号、段内页号及页内地址三部分所组成
- 一个进程有一张段表和多张页表,段表项为页表始址和页表长度
- 段页式系统配置一个段表寄存器,存放段表始址和段长TL
- 一次访问数据需三次访问内存,可用快表提高转换速度
第五章
虚拟存储器
- 引入
- 存储器管理方式:要求将作业全部装入内存才能运行
- 缺点
- 作业很大时无法运行
- 内存不能容纳大量作业
- 原因:内存不够大
- 解决办法
- 物理扩充
- 逻辑扩充
- 虚拟存储器(vm):从逻辑上实现内存扩展功能
- 可运行大作业和更多道数作业
- 改善系统性能
常见存储管理方式特征和局部性原理
- 存储器管理方式:传统存储器管理方式
- 特征
- 一次性:作业必须一次性的全部装入内存后方能开始运行(限制作业道数和作业大小)
- 驻留性:作业被装入内存后,整个作业都一直驻留在内存中,其中任何一部分都不会被换出,直至作业运行结束(阻塞性也占内存,部分程序根本用不上(如错误处理))
- 以上特征导致浪费宝贵内存:无用程序占用内存,大作业无法运行
- 程序局部性
- 在一较短时间内,程序的执行仅局限于某个部分
- 程序运行存在局部性现象
- 局限性表现在两个方面
- 时间局部性:存在大量循环
- 空间局部性:如程序顺序执行,数组访问等
- 虚拟存储器基本工作情况
- vm工作原理
- 根据局部性原理,只装入部分程序就开始运行,其余在磁盘
- 若访问的页(段)不在内存,产生缺页(段)中断
- 由OS请求调页功能调入内存再运行
- 若内存满则置换再调入
- 优点:
- 小内存运行大程序
- 更多作业并发执行
虚拟存储器的定义和特征
- 虚拟存储器的定义
- 虚拟存储器,简称VM,是指具有请求调入和置换功能,能从逻辑上对存储器容量进行扩充的一种存储器
- VM容量(逻辑容量)由内存容量和外存容量之和决定,速度接近于内存速度,位成本接近于外存
- VM是性能优越的存储器管理技术,广泛用于各种机型
- 虚拟存储器特征
- 多次性:传统存储器是一次性,vm多次调入
- 对换性:传统存储器是常驻性,vm多次对换
- 虚拟性:从逻辑上扩充容量,运行更大的程序
虚拟存储器的实现方法
- 分页请求系统,也称为页式虚拟存储器
- 分段请求系统,也称为段式虚拟存储器
- 段页式虚拟存储器
- 分页请求系统
- 在分页系统基础上增加请求调页和页面置换功能的页式VM
- 以页为单位转换
- 硬件支持:
- 请求分页的页表机制:纯分页基础上增加若干表项
- 缺页中断机构
- 地址变换机构
- 软件支持
- 实现请求分页的软件和页面置换的软件
- 分段请求系统
- 在分段系统基础上增加请求调段和分段置换功能的段式VM
- 以段为单位转换
- 硬件支持:
- 请求分段的段表机制:纯分段基础上增加若干表项
- 缺段中断机构
- 地址变换机构
- 软件支持
- 实现请求分段的软件和分段置换的软件
请求分页存储管理方式
- 请求分页系统是在基本分页基础上增加请求调页和页面置换功能
- 以页面为单位调入调出,页面大/、固定
- 比请求分段系统简单,是最常用虚拟存储器
- 请求分页系统的硬件支持
- 一定容量的内存和外存
- 请求页表机制、缺页中断机构以及地址变换机构
请求页表机制
- 请求页表作用
- 请求分页系统页表增加四个表项:
- 状态位(存在位)p:指示是否在内存中
- 访问字段A访问次数或者未访问时间,供置换箅法参考
- 修改位M,是否修改供页面置换时参考
- 外存地址:磁盘地址,如柱面、磁道、扇区
缺页中断机构
访问的页不在内存时缺页中
断,请求OS调入该页和常规中断一样处理,特别
之处:
在指令执行期间产生和处理
缺页中断信号一条指令执行期间可能产生
多次缺页中断3。
地址变换机构
请求分页内存分配的三个问题
- 使进程运行最小物理块数的确定
- 采用哪种分配策略,块数固定OR可变
- 各进程分配的物理块数相同0R不同
最小物理块确定
- 进程分配的物理块减少,则缺页率上升,执行速度降低
- 最小物理块数是指能保证进程正常运行所需的最小物理块数
- 最小物理块数与计算机硬件结构有关,取决于指令的格式、功能和寻址方式
- 能存放一条指令及所需要的操作数的最大可能页面数
内存分配策略
- 请求分页系统中有两种内存分配策略:固定和可变分配策略
- 页面置换也可采取两种策略:全局置换和局部置换
- 共有三种适用的策略
- 固定分配局部置换
- 固定分配:进程物理块数固定
- 局部置换:缺页时只从该进程页面选择一页换出
- 进程物理块数根据进程类型或程序员,管理员建议确定
- 缺点:难以确定物理块数
- 可变分配全局置换
- 可变分配:先确定一定数目物理块,运行期间可增减
- 全部置换:缺页时从整个系统空闲物理块分配或者所有进程页面选择一页换出
- 可变分配局部置换
- 可变分配:根据进程类型及程序员请求分配一定数目物理块运行期间可增减(根据缺页率)
- 局部置换:缺灾时只从该嚇枣面选择一页换出
- 进程物理块数可调整
- 缺页率很高时增加若干,直到缺页率降到某限值
- 缺页率很低时适当减少
物理块分配算法
- 采用固定分配策配系统所有物理块的算法:
- 平均分配算法:进程平均,看似公平其实不公平
- 按比例分配算法:根据进程大小按比例分配,n个进程,共m块,每个个进程的页面数为Si
- 考虑优先权分配算法:内存物理块分两部分,一部分按比例分配;另一部分按进程优先权分配,高优先进程适当增加;重要的实时控制系统则完全按优先权分配
页面调入策略
- 预调页策略
- 请求调页策略
何时调入页面
- 预调页策略
- 以预测为基础,将那些预计不久会访问的页面预先调入
- 进程第一次运行时将程序员指定的页调入
- 每当被调度时将工作集的所有页面调入
- 请求调页策略,缺页中断时调入,一次一页,开销大,IO频繁
从何处调入页面
- 请求分页系统外存分两部分:文件区,对换区
- 文件区离散分配(访问慢),对换区连续分配(访问快)
- 系统拥有足够对换空间:全部从对换区调入,开始
时进程全部装入对换区- 系统缺少对换空间:未被修改的文件从文件区调入,被修改的部分从对换区调入或调出
- UNIX方式:未运行过的页面从文件区调入;运行过的从对换区调入·共享时不用调入
页面调入过程
- 访问的页面未在内存(存在位为0),发出缺页中断
- 中断机构保留断点和cpu环境,分析中断原因转入页中断ISR
- 根据页表项找到外存地址
- 若内存有空闲页则启IO调入,修改页表和决表
- 若内存满,按照置换算法换出一页(若修改过则写入磁盘)再调入、修改页表和快表
- 根据修改后的页表访问调入页
缺页率
- 影响缺页率因素
- 页面大小,页面越大越低
- 进程分配物理块数,块数越多越低
- 页面置换算法;却用缺页率衡量去优劣
- 程序固有特性,局部化程度越高越低
页面置换算法
- 引入
- 调入时但内存不足则要置换
- 抖动:刚换出的页面又要访问,大部分时间浪费在置换上
- 页面置换去用于选择要换出的页面,直接影响系统性能
- 好的置换算法要有低更换频率。以后不用或者很长时间不访问的页面
- 最佳置换算法是理想化的算法,性能好但无法实现,用作标准
- 先进先出算法最直观,性能最差,很少用
最佳置换算法
- 选择以后永不使用,或在最长(未来)时间内不再被访问页面
- 缺页率最低,但该算法无法实现
- 利用该算法去评价其他算法
- 进程运行时,当进程要访问7, 0, 1三个页面时都会产生缺页中断
- 按照页面访问顺序,当进程要访问页面2时,内存中没有页面2,产生缺页中断。内存中的三个页面7, 0, 1,
- 按照访问页面的顺序,页面7被再次访问的时间最长,所以淘汰页面7,页面2装入物理块1
- 按照页面访问顺序,当进程要访问页面0时,页面0在物理块2中,不会产生缺页中断
- 按照页面访问顺序,当进程要访问页面3时,内存中没有页面3,产生缺页中断。内存中的三个页面2, 0, 1,
- 按照访问页面的顺序,页面1被再次访问的时间最长,所以淘汰页面1,页面3装入物理块3
- 按照页面访问顺序,当进程要访问页面0时,页面0在物理块2中,不会产生缺页中断
- 按照页面访问顺序,当进程要访问页面4时,内存中没有页面4,产生缺页中断。内存中的三个页面2, 0, 3
- 按照访问页面的顺序,页面0被再次访问的时间最长,所以淘汰页面0,页面4装入物理块2
先进先出(FIFO)算法
- 最早出现的置换算法
- 总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰
- 页面按先后次次序,并设置一个指向最老页面的替换指针
- 算法实现简单,但无法保证经常用到的页面不被淘汰
- 进程运行时,当进程要访问7, 0, 1三个页面时都会产生缺页中断
- 按照页面访问顺序,当进程要访问页面2时,内存中没有页面2,产生缺页中断。内存中的三个页面7, 0, 1,页面7最先进入内存,所以淘汰页面7,页面2装入物理块1
- 按照页面访问顺序,当进程要访问页面0时,页面0在物理块2中,不会产生缺页中断
- 按照页面访问顺序,当进程要访问页面3时,内存中没有页面3,产生缺页中断。内存中的三个页面2, 0, 1,页面0最先进入内存,所以淘汰页面0,页面3装入物理块2
- 按照页面访问顺序,当进程要访问页面0时,内存中没有页面0,产生缺页中断。内存中的三个页面2, 3, 1,页面1最先进入内存,所以淘汰页面1,页面0装入物理块3
- 按照页面访问顺序,当进程要访问页面4时,内存中没有页面4,产生缺页中断。内存中的三个页面2, 0, 3,页面2最先进入内存,所以淘汰页面2,页面4装入物理块1
- 以此类推,便可得到如图情况
最近最久未使用(LRU)算法
FIFO算法:页面调入的先后并不反映页面使用情况
LRIU算法去根据页面调入内存后的使用情况做决策,淘汰最近最久未使用的页面
增加访问字段,记录后一次访问经过的时间,淘汰最大值页面
最佳算法"向后看",LRU"向前看"
LRU效果较好,但要求较多硬件支持
首先,我们先借助栈来实现各页面最近最久未使用的排序
按照页面访问顺序,页面7放入栈底,然后是页面0,再然后是页面1,栈已满 当访问页面2时,栈底的页面7出栈,页面2放在栈顶 当访问页面0时,栈中已有页面0,则重置,页面0放在栈顶 当访问页面3时,栈底的页面1出栈,页面3放在栈顶 当访问页面0时,栈中已有页面0,则重置,页面0放在栈顶 以此类推,便可得到如图栈的情况
然后进程运行时,当进程要访问7, 0, 1三个页面时都会产生缺页中断
按照页面访问顺序,当进程要访问页面2时,内存中没有页面2,产生缺页中断。内存中的三个页面7, 0, 1,页面7在内存中最近一段时间内最长时间未被使用,所以淘汰页面7,页面2装入物理块1。可以观察到在栈中对应访问页面2下,有页面2,1,0,页面7已经被淘汰了,所以让页面2代替页面7的位置
按照页面访问顺序,当进程要访问页面0时,页面0在物理块2中,不会产生缺页中断
按照页面访问顺序,当进程要访问页面3时,内存中没有页面3,产生缺页中断。此时内存中有页面2,0,1。观察对应下面栈中有页面3,0,2,所以让页面3代替页面1的位置
按照页面访问顺序,当进程要访问页面0时,页面0在物理块2中,不会产生缺页中断
按照页面访问顺序,当进程要访问页面4时,内存中没有页面4,产生缺页中断。此时内存中有页面2,0,3。观察对应下面栈中有页面4,0,3,所以让页面4代替页面2的位置
以此类推,便可得到如图情况
LRU算法的硬件支持
- 寄存器:每个内存页面配置一个移位寄存器
R=Rn-1Rn-2Rn-3…R2R1R0访问时将Rn-1置1,定期右移一位,选数值最小的页面。
- 栈:利用特殊栈保存当前页面号。访问某页面时,将其从栈移出并压入栈顶。栈顶是最新被访问页面,栈底是最近最未使用页面。
最少使用(LFU)算法
- LFU算法为每个页面设置一个移位寄存器/计数器,记录页面被访问的频率
- 选择在最近时期使用次数最少的页面淘汰
- 用计数器不现实,只能用移位寄存器
- 思路:每次访问最高位置1,定期右移,选取最小值页面
- 既可实现LFU,又可实现LRU
- 不能完全反映近期页面使用情况
CLOCK算法
- LRU效果好但要求较多硬件,成本高
- 实际中使用LRU近似算法,例如Clock
- 简单的CLOCK算法
- 为每页设置一访问位,将所有内存页面链接成一个循环队列
- 页面访问时访问位置1
- 若为0则淘汰;若为1则置0再给一次机会,FIFO检查下一页面
- 因循环检查,故称CLOCK算法
- 只反映页面是否访问,换出未访问页面,也称最近未使用NRU
- 按照页面访问顺序,当进程要访问页面4时,内存中没有页面4,产生缺页中断。内存中的三个页面2, 0, 3
- 按照访问页面的顺序,页面0被再次访问的时间最长,所以淘汰页面0,页面4装入物理块2