目录
一、引论
1.1、操作系统的目标
方便性:
有效性:
可扩充性:
开放性:
1.2、操作系统的作用
用户与计算机硬件系统之间的接口:
计算机系统资源的管理者:
实现对计算机资源的抽象:
1.3、操作系统的发展过程
1.4、操作系统的基本特征
并发(Concurrence)
共享(Sharing)
虚拟(Virtual)
异步(Asynchronism)
1.5、操作系统的运行环境
硬件支持:
操作系统内核:
处理器的双重工作模式:
特权指令和非特权指令
中断与异常
1.6、操作系统的主要功能
处理机管理功能
存储器管理功能
设备管理功能
文件管理功能
操作系统与用户之间的接口
现代操作系统的新功能
1.7、操作系统结构设计
简单结构
模块化结构
分层式结构
微内核OS结构
1.8、系统调用
二、进程的描述与控制
2.1前趋图和程序执行
程序顺序执行
前趋图
程序并发执行
2.2进程的描述
进程的定义
进程控制块(process control block,PCB)
进程的特征
进程的状态及转换
2.3进程控制
介绍
进程创建
进程终止
进程的阻塞与唤醒
进程的挂起与激活
2.4进程通信
概念
2.5线程的基本概念
引入进程的目的
进程的2个基本属性
线程是什么
提出线程的目的
线程与进程的比较
线程的实现
内核支持线程KST:在内核空间实现
用户级线程ULT:在用户空间实现
三、处理机调度与死锁
3.1处理机调度概述
处理机调度层次
高级调度
中级调度
低级调度
处理机调度
进程调度的任务
进程调度机制(调度程序分为3部分)
进程调度的方式
处理机调度算法的目标
评价指标
3.2调度算法
介绍
先来先服务(FCFS)算法特征
短作业优先(SJF)调度算法
优先级调度算法(PR)
高响应比优先调度算法(PR的特例)
时间片轮转算法(RR)
多级队列调度算法
多级反馈队列调度算法
基于公平原则的调度算法
3.3实时调度
实时任务,都联系着一个截止时间:
实时调度应具备一定的条件:
非抢占式调度算法
抢占式调度算法
最早截止时间优先(EDF)调度算法
最低松弛度优先LLF算法
优先级倒置现象
3.4Linux进程调度
普通进程调度:
实时进程调度:
3.5死锁概述
概念
产生死锁的必要条件
死锁原因
处理死锁的方法
3.6预防死锁
互斥:
请求和保持:
非抢占:
循环等待:
3.7避免死锁
安全状态
不安全状态
安全状态和不安全状态的区别
基本事实
银行家算法
3.8死锁的检测与解除
基本事实
资源分配图的简化
死锁定理
死锁的解除
进程终止
其他问题
通信死锁
活锁
饥饿
四、进程同步
4.1进程同步的概念
概念
同步机制应遵循的准则
进程同步机制
4.2软件同步机制
4.3硬件同步机制
4.4信号量机制 (推荐看B站)
信号量-软件解决方案:
整型信号量
记录型信号量
五、存储器管理
5.1存储器的层次结构
概念
5.2程序的装入和链接
程序的运行步骤:
物理地址和逻辑地址
内存保护的实现:硬件
程序的装入
程序的链接
5.3对换与覆盖
5.4连续分配存储管理方式
单一连续分配
固定分区分配
动态分区分配
动态可重定位分区分配
5.5分页存储管理方式
页表
页表的实现
页表结构
5.6分段存储管理方式
六、虚拟存储器
6.1虚拟存储器概述
虚拟存储器定义
虚拟存储器的特征
虚拟存储器的实现方法
6.2请求分页存储管理方式
请求分页中的硬件支持
请求分页中的内存分配
页面调入策略
6.3页面置换算法
种类
最佳置换算法(OPT)
先进先出置换算法(FIFO)
最近最久未使用置换算法(LRU)
最少使用算法(LFU)
Clock置换算法
页面缓冲算法PBA
6.4抖动与工作集
抖动:一个进程的页面经常换入换出
产生抖动的原因
工作集
抖动的预防方法
6.5请求分段存储管理方式
七、输入/输出系统
7.1I/O系统的功能、模型和接口
I/O系统的基本功能
各种I/O模块之间的关系
I/O系统接口
7.2I/O设备和设备控制器
I/O设备的类型
设备与控制器之间的接口
设备控制器
内存映像I/O
I/O通道
I/O设备的控制方式
7.3中断和中断处理程序
介绍
对多中断的处理方式
Linux中的中断处理
7.4设备驱动程序
7.5与设备无关的I/O软件
7.6用户层的I/O软件
7.7缓冲区管理
引入缓冲区的原因:
单缓冲
双缓冲
环形缓冲区
缓冲池
缓存和缓冲
7.8磁盘性能概述和磁盘调度
磁盘结构
磁盘的类型
磁盘访问时间
早期的磁盘调度算法
先来先服务FCFS调度算法
最短寻道时间优先SSTF
SCAN算法
循环扫描算法C-SCAN
CLOCK
NStepSCAN算法
FSCAN算法
八、文件管理
8.1文件和文件系统
数据项、记录和文件
文件类型
文件系统的层次结构
文件系统的功能
与文件系统有关的软件
文件操作
8.2文件的逻辑结构
文件结构
文件名和文件类型
顺序文件
索引文件
顺序索引文件
一、引论
1.1、操作系统的目标
方便性:
- 通过OS命令操纵计算机,方便用户
有效性:
- 提高系统资源的利用率
- 提高系统吞吐量
可扩充性:
- OS必须具有很好的可扩充性
- 与OS的结构有紧密的联系
开放性:
- 遵循世界标准规范。特别是开放系统互连OSI
1.2、操作系统的作用
用户与计算机硬件系统之间的接口:
- 命令方式(UNIX、DOS命令)
- 系统调用方式(API)
- GUI方式(Windows、LINUX)
计算机系统资源的管理者:
- 处理机管理、存储器管理、I/O设备管理、文件管理
实现对计算机资源的抽象:
- 裸机:无软件的计算机系统
- 虚拟机:覆盖了软件的机器,向用户提供一个对软件操作的抽象模型
1.3、操作系统的发展过程
- 无操作系统的计算机系统(人工操作方式、脱机I/O方式)
- 单道批处理系统
- 多道批处理系统
- 分时系统
- 实时系统
- 微机操作系统
- 嵌入式操作系统
- 网络操作系统
- 分布式操作系统
1.4、操作系统的基本特征
并发(Concurrence)
- 并行性:两个或多个事件在同一时刻发生
- 并发性:两个或多个事件在同一时间间隔内发生
- 引入进程(任务):动态、并发
共享(Sharing)
系统中的资源可供内存中多个并发执行的进程共同使用
- 互斥共享方式(临界资源)
- 同时访问方式
虚拟(Virtual)
- 时分复用技术:虚拟处理及、虚拟设备
- 空分复用技术:虚拟存储
异步(Asynchronism)
- 进程的异步性:进程是以人们不可预知的速度向前推进的
1.5、操作系统的运行环境
硬件支持:
- 引导程序:位于固件(定位OS内核并将其加载到内存中)
- 指令:CPU执行
- 事件:硬件中断或软件中断引起
- 执行程序:位于内存
- 程序:位于外存
操作系统内核:
常驻内存,通常与硬件紧密相关
支撑功能:
- 中断处理
- 时钟管理
- 原语操作
- 由若干条指令组成,用于完成一定任务
- 原子操作:要么不做,要么全做,不可分割
资源管理功能:
- 进程管理、存储器管理、设备管理
处理器的双重工作模式:
- 特权指令:如有误用,有可能引起系统崩溃的提示
- 内核态(管态、系统态):执行包括特权指令在内的一切指令
- 用户态(目态):不能执行特权指令
- 由硬件提供模式位
- 提供了区分系统正在运行用户代码或内核代码的能力
- 系统调用切换运行模式到内核态,并将调用结果返回给用户
特权指令和非特权指令
特权指令:在内核态下运行的指令
- 不仅能访问用户空间,还能访问系统空间
- 如启动外部设备、设置系统时钟、管终端、切换执行状态、I/O指令。
非特权指令:在用户态下运行的指令
- 应用程序所使用的都是非特权指令
- 防止应用程序的运行异常对系统造成破坏
- 仅能访问用户空间
中断与异常
- 操作系统是终端驱动的,OS总在等待某个事件的发生,事件总是由中断或异常引起的
- 中断(interrupt):由硬件引起
- 异常/陷阱(trap):由软件引起
- 出错(如出书为0或无效存储访问)
- 用户程序的特定请求(如执行OS的某个服务)
1.6、操作系统的主要功能
处理机管理功能
- 进程控制:创建进程、撤销(终止)进程、状态转换
- 进程同步:信号量机制
- 进程通信:直接通信、间接通信
- 调度:作业调度、进程调度
存储器管理功能
- 内存分配和回收:内存分配、内存回收
- 内存保护:确保每个用户程序仅在自己的内存空间进行、决不允许用户程序访问操作系统的程序和数据
- 地址映射:逻辑地址转换为物理地址
- 内存扩充(虚拟存储技术):请求调入功能、置换功能
设备管理功能
- 缓冲管理:缓冲区机制
- 设备分配
- 设备处理:设备驱动程序
主要任务:完成I/O请求、提高CPU和I/O设备的使用率
文件管理功能
- 文件存储空间的管理
- 目录管理:按名存取
- 文件的读/写管理和保护:文件的读/写管理、文件保护
操作系统与用户之间的接口
用户接口:
- 联机用户接口:命令方式CLI
- 脱机用户接口
- 图形用户接口GUI
程序接口:
- 系统调用:能完成特定功能的子程序
现代操作系统的新功能
- 系统安全:认证、密码、访问控制、反病毒技术
- 网络功能服务:网络通信、资源管理、应用互操作
- 支持多媒体:接纳控制技术、实时调度、多媒体文件的存储
1.7、操作系统结构设计
简单结构
OS是无结构的,是为数众多的一组过程的集合,内部复杂、混乱。也称整体系统结构。如:MS-DOS,早期的UNIX。
模块化结构
将OS按功能划分成若干个模块、并规定好各模块间的接口,称为“模块-接口法”
优点:
- 提高OS设计的正确性、可理解性和易维护性
- 增强OS的可适应性
- 加速OS的开发过程
大部分现代OS采用可加载的内核模式来设计
- 内核有一组核心组件,提供核心服务
- 其他服务可在内核运行时动态实现(动态链接)
- 每个组件在需要时被加载到内核
- 例子:Linux、Mac OS X、Solaris以及Windows
分层式结构
操作系统划分为若干层,在低层上构建高层
- 高层仅依赖于邻接它的底层
- 底层(0层)为硬件;最高层(N层)为用户层
优点
- 易保证系统的准确性
- 可保证系统的易维护性和可扩展性
缺点
- 系统效率低
例子:THE、Multics
微内核OS结构
基本概念:
- 足够小的内核
- 基于C/S模式
- 应用“机制与策略分离”原理
- 采用面向对象技术
基本功能:进程管理、低级存储器管理、中断和陷入处理
实例:Mach OS、Windows 200/XP
优点:
- 提高了系统的可扩展性
- 增强了系统的可靠性
- 可移植性强
- 提供了对分布式系统的支持
- 融入了面向对象技术
存在的问题:
- 运行效率有所降低
- 主要原因:在完成一次客户对操作系统提出的服务请求时,需要利用消息实现多次交互和进行用户/内核模型与上下文的多次切换
1.8、系统调用
系统调用目的:使应用程序可以通过它间接调用OS内核中的相关过程,取得相应的服务
系统调用概念:
- 应用程序请求OS内核完成某功能时的一种过程调用
- 用户与内核的接口
与一般过程调用的区别:
- 运行在不同的系统状态
- 状态的切换
- 返回问题
- 嵌套调用
系统调用的类型:
- 进程控制类:创建和终止进程、获得和设置进程属性、等待某事件出现的系统调用
- 进程通信类:用于进程之间通信的系统调用
- 文件操纵类:打开和关闭文件、创建和删除文件、读写文件的系统调用
- 设备管理类:申请设备、释放设备、设备I/O重定向、获得和设置设备属性等系统调用
- 信息维护类:获得包括有关系统和文件的时间信息、OS版本、当前用户、空闲内存、磁盘等。
二、进程的描述与控制
2.1前趋图和程序执行
程序顺序执行
- 一个较大的程序通常都由若干个程序段组成
- 程序在执行时,必须按照某种先后次序诸葛执行,仅当前已操作完成后,才能执行后续操作
- 顺序性 ;封闭性;可再现性
前趋图
- 有向无循环图,用于描述进程之间执行的先后顺序
- 结点表示进程或程序段,有向边表示前趋关系
程序并发执行
-
采用多道程序技术,将多个程序同时装入内存,使之并发运行
特征:间断性、失去封闭性、不可再现性
间断性:
- 并发程序之间相互制约
- 执行——暂停执行——执行
失去封闭性:
- 多个程序共享全机资源
- 执行状态受外界因素影响
不可再现性:
- 程序经过多次执行后,虽然其执行时的环境和初始条件都相同,但得到的结果却各不相同
2.2进程的描述
进程的定义
- 一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程
- 进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位
- 程序段、相关的数据段和PCB这3部分构成进程实体,一般简称为进程
进程控制块(process control block,PCB)
- 是进程的一部分,是操作系统中最重要的记录型数据结构,是进程存在的唯一标志,常驻内存
PCB的作用:
- 作为独立运行单位的标志
- 能实现间断性运行方式
- 提供进程管理所需要的信息
- 提供进程调度所需要的信息
- 实现与其他进程的同步与通信
PCB的信息:
- 进程标识符
- 处理及状态
- 进程调度信息
- 进程控制信息
PCB的组织方式:
- 线性方式
- 链接方式
- 索引方式
进程的特征
- 动态性(最基本的特征):生命期
- 并发性:一段时间内同时运行
- 独立性:进程实体是一个能独立运行的基本单位、是系统中独立获得资源和独立调度的基本单位
- 异步性:按各自独立的、不可预知的速度向前推进
进程的状态及转换
就绪态:
- 一个较大的程序通常都由若干个程序段组成
- 程序在执行时,必须按照某种先后次序逐个执行,仅当前一操作执行完后,才能执行后续操作
执行状态:以获得CPU,正在执行的状态
- 单处理机:一个进程处于执行状态
- 多处理及:多个进程处于执行状态
阻塞状态:
- 正在执行的进程由于发生某事件而暂时无法继续执行的状态
- 典型事件:请求I/O、申请缓冲空间
- 根据阻塞原因,设置多个阻塞队列
2.3进程控制
介绍
- 进程管理最基本的功能
- 一般由OS内核中的原语实现
- 包括:进程创建、进程终止、进程阻塞与唤醒、进程挂起与激活
进程创建
- 进程具有层次结构
- 引起进程创建的事件:用户登录、作业调度、提供服务、应用请求
- 进程图:描述进程家族关系的有向树
- 进程创建过程:申请空白PCB、分配所需资源、初始化PCB、插入就绪队列
进程终止
引起进程终止的事件:正常结束、异常结束、外界干预
进程的终止过程:
- 根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态
- 若被终止的进程正处于执行状态,应立即终止该进程的执行,并设置调度标志为真,用于指示该进程被终止后应和重新进行调度
- 若该进程还有子孙进程,应将其所有子进程终止
- 将该进程所拥有的所有资源,归还其父进程或系统
- 将被终止进程(PCB)从所在队列中移去
进程的阻塞与唤醒
引起进程阻塞与唤醒的事件:
- 向系统请求共享资源失败
- 等待某操作的完成
- 新数据尚未到达
- 等待新任务的到达
进程阻塞过程:
- 阻塞原语Block()
- 进程的阻塞是进程自身的一种主动行为
- 具体过程:停止执行、状态由执行改为阻塞、将PCB插入阻塞队列
进程唤醒过程:
- 唤醒原语Wakeup()
- 具体过程:从阻塞队列中移除、状态由阻塞改为就绪、将PCB插入就绪队列
- 必须成对使用Block和Wakeup原语
进程的挂起与激活
Suspend()原语与Active()原语
2.4进程通信
概念
- 进程通信是指进程间的信息交换
低级进程通信:进程的同步与互斥
- 效率低
- 通信对用户不透明
高级进程通信
- 使用方便
- 高效地传送大量数据
共享存储器系统
- 基于共享数据结构的通信方式(效率低)
- 基于共享存储区的通信方式(高级)
管道通信
- 管道:用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名pipe文件
- 管道机制的协调能力:互斥、同步、对方是否存在
消息传递系统
- 直接通信方式
- 间接通信方式(通过邮箱)
C/S模式
- 套接字(Socket)
- 远程过程调用(RPC)和远程方法调用(RMI,Java)
2.5线程的基本概念
引入进程的目的
- 使多个程序并发执行
- 提高资源利用率级系统吞吐量
进程的2个基本属性
- 进程是一个可拥有资源的独立单位
- 进程是一个可独立调度和分派的基本单位
线程是什么
在进程内部增加一类实体,满足以下特性:
- 实体之间可以并发执行
- 实体之间可以共享相同的地址空间
这种实体就是线程(Thread)
优点:
- 一个进程中可以同时存在多个线程
- 各个线程之间可以并发执行
- 各个县城直线可以共享地址空间和文件等资源
缺点:
- 一个线程崩溃,会导致其所属进程的所有线程崩溃
提出线程的目的
- 减少程序在并发执行时所付出的时空开销:创建、撤销、切换
- 使OS具有更好的并发性
- 适用于SMP结构的计算机系统
进程是拥有资源的基本单位(传统进程称为重型进程)
线程作为调度和分派的基本单位(又称为轻型进程)
线程与进程的比较
- 进程是资源分配单位,线程是CPU调度单位
- 进程拥有一个完整的资源平台,而线程只独享指令流的必要资源,如寄存器和栈
- 线程具有就绪、阻塞和运行三种基本状态和状态间的转换关系
- 线程能减少并发执行的时间和空间开销
- 创建时间短
- 终止时间短
- 切换时间短
- 同一进程个各线程间共享内存和文件资源,可不通过内核进行直接通信
线程的实现
实现方式:
- 内核支持线程KST
- 用户级线程ULT
- 组合方式
具体实现:
- 内核支持线程的实现(利用系统调用)
- 用户级现成的实现(借助中间系统)
内核支持线程KST:在内核空间实现
优点:
- 在多处理机系统中,内核可同时调度同一进程的多个线程
- 如果一个线程阻塞了,内核可调度其他线程(同一或其他进程)
- 线程的切换比较快,开销小
- 内核本身可采用多线程技术,提高执行速度和效率
缺点:对用户线程切换,开销较大
用户级线程ULT:在用户空间实现
优点:
- 线程切换不需要转换到内核空间
- 调度算法可以是进程专用的
- 线程的实现与OS平台无关
缺点:
- 系统调用的阻塞问题
- 多线程应用不能利用多处理机进行多重处理的优点
三、处理机调度与死锁
3.1处理机调度概述
处理机调度层次
- 高级调度(长程调度/作业调度)
- 低级调度(短程调度/进程调度)
- 中级调度(中程调度/内存调度)
高级调度
- 调度对象:作业
- 根据某种算法,决定将外存上处于后备队列中的作业调入内存,并为它们创建进程和分配必要资源。然后,将新创建的进程排在就绪队列上等待调度
- 主要用于多道批处理系统中
中级调度
- 将暂不运行的进程,调至外存等待
- 将处于外存上的急需运行的进程,调入内存运行
- 即“对换”功能
低级调度
- 调度对象:进程
- 根据某种调度算法,决定就绪队列中的哪个进程应获得处理机
- 应用在多道批处理、分时和实时OS
处理机调度
- 从就绪队列中挑选下一个占用CPU运行的进程
- 从多个可用CPU中挑选就绪进程可使用的CPU资源
进程调度的任务
- 保存处理及的现场信息
- 按某种算法选取进程
- 把处理器分配给进程
进程调度机制(调度程序分为3部分)
- 排队器:用于将就绪进程插入相应的就绪队列
- 分派器:用于将选定的进程移出就绪队列
- 上下文切换器:进行新旧进程之间的上下文切换
进程调度的方式
分为非抢占方式和抢占方式,现代OS广泛采用抢占方式,抢占方式有以下三个原则
- 优先权原则:允许优先权高的新到进程抢占当前进程的处理机
- 短作业优先原则:短作业可以抢占当前较长作业的处理机
- 时间片原则:各进程按时间片运行,当一个时间片用完后,便停止该进程的执行而重新进行调度
处理机调度算法的目标
共同目标:资源利用率、公平性、平衡性、策略强行执行
批处理系统的目标:平均周转时间短、系统吞吐量高、处理及利用率高
分时系统的目标:响应时间快、均衡性
实时系统的目标:截至时间的保证、可预测性
评价指标
- 周转时间:从作业提交给系统开始,到作业完成为止的这段时间间隔
- 带权周转时间:权值为作业周转时间T与系统为之服务时间TS之比
- 响应时间:从用户通过键盘提交请求开始,直到系统首次显示出处理结果为止的一段时间
- 等待时间:进程在就绪队列中等待调度的所有时间之和
3.2调度算法
介绍
先来先服务(FCFS)
短作业优先调度(SJF)
优先权调度(PR)
时间片轮转调度(RR)
多级队列调度
多级反馈队列调度
基于公平原则的调度算法
先来先服务(FCFS)算法特征
既可用于作业调度,也可用于进程调度
优点:简单
缺点:
- 平均等待时间波动较大,因为段进程可能排在长进程后面
- I/O和CPU资源利用率较低,因为CPU密集型进程会导致I/O设备闲置时,I/O密集型进程也会等待
短作业优先(SJF)调度算法
既可用于作业调度,也可用于进程调度
- 对作业:从后被队列中选择若干个评估运行时间最短的作业
- 对进程:关联到每个进程下次运行的CPU区间长度,调度最短的进程
对进程调度,SJF有两种模式
- 非抢占式SJF
- 抢占式SJF:抢占发生在有比当前进程剩余时间片更短的进程到达时,也成为最短剩余时间优先调度
SJF时最优的(对一组特定的进程而言),它给出了最短的平均等待时间
缺点:
- 需要预知运行时间
- 对长作业不利(饥饿)
- 采用SJF算法时,人机无法实现交互
- 完全未考虑作业的紧迫程度
优先级调度算法(PR)
既可用于作业调度,也可用于进程调度
基于紧迫程度,由外部赋予作业相应的优先级,调度算法根据优先级进行调度:
- 每个进程都有一个优先数,优先数为整数
- 默认:小的优先数具有高优先级
- 目前主流的操作系统调度算法
高响应比优先调度算法是一种优先级调度算法,用于作业调度
优先级调度算法的类型:
- 非抢占式
- 抢占式
优先级类型:
- 静态优先级
- 创建进程时确定优先数(整数),在进程的整个运行期间保持不变
- 简单易行,系统开销小
- 不够精确,可能会出现优先级低的进程长期没有被调度的情况
- 动态优先级
- 创建进程时先赋予其一个优先级,然后随着时间的增加而改变
优点:
- 实现简单,考虑了进程的紧迫程度
- 灵活,可模拟其他算法
存在问题:饥饿 ;解决方法:老化
高响应比优先调度算法(PR的特例)
- 既考虑了作业的等待时间,又考虑了运行时间
- 优先级=(等待时间+要求服务时间)/要求服务时间
- 响应比=响应时间/要求服务时间
- 如等待时间相同,运行时间越短,类似于SJF
- 如运行时间相同,取决于等待时间,类似于FCFS
- 长作业可随其等待时间的增加而提高,也可得到服务
- 缺点:每次调度之前,都需要计算响应比,增加系统开销
时间片轮转算法(RR)
时间片:分配处理机资源的基本事件单元
算法思路:时间片结束时,按FCFS算法切换到下一个就绪进程
- 专门为分时系统设计,类似于FCFS,但增加了抢占
- 为每个进程分配不超过一个时间片的CPU。时间片用完后,该进程被抢占并插入就绪列表末尾,循环执行
- 假定就绪队列中有n个进程、时间片为q,则每个进程每次得到1/n的、不超过q单位的成块CPU时间,没有任何一个进程的等待时间会超过(n-1)q单位
通常,RR的平均周转时间比SJF长,但响应时间要短一些
进程切换实际:
- 若一个时间片尚未用完,正在运行的进程便已经完成,就立即激活调度程序,将它从就绪列表中删除,再调度就绪队列中队首的进程运行,并启动一个新的时间片
- 时间片设置应考虑在一个时间片用完时,计时器中断处理程序被激活。如果进程尚未运行完毕,调度程序将把它送往就绪队列的末尾
在当前进程A的一个时间片用完时,恰好有新进程B到达,则就绪队列的末尾的排序应该是BA。
确定时间片大小的因素:
- 系统对响应时间的要求
- 就绪队列中进程的数目
- 系统的处理能力
多级队列调度算法
就绪队列从一个分为多个,如:
- 前台【交互式】
- 后台【批处理】
每个队列有自己的调度算法,如:
- 前台——RR
- 后台——FCFS
调度需在队列间进行:
- 固定优先级调度,即前台运行完后再运行后台,有可能产生饥饿
- 给定时间片调度,即每个队列得到一定的CPU时间,进程在给定时间内执行;如80%的时间执行前台的RR调度,20%的时间执行后台的FCFS调度
多级反馈队列调度算法
进程能在不同队列间移动
其他调度算法的局限性:
- 短进程优先算法,仅照顾短进程而忽略了长进程
- 如果并未指明进程的长度,则短进程优先和基于进程长度的抢占式调度算法都将无法使用
优点:
- 不必事先知道各种进程所需的执行时间
- 可以满足各种类型进程的需要
基于公平原则的调度算法
主要考虑调度的公平性
保证调度算法:
- 性能保证,而非优先运行
- 如保证处理及分配的公平性
公平分享调度算法:
- 调度的公平性主要针对用户而言
- 使所有用户都获得相同的处理及时间或时间比例
3.3实时调度
实时调度是针对实时任务的调度
实时任务,都联系着一个截止时间:
- 硬实时HRT任务
- 软实时SRT任务
实时调度应具备一定的条件:
- 提供必要的信息:就绪时间、开始截止时间和完成截止时间、处理时间、资源要求、优先级
- 系统处理能力强(周期性)
- 采用抢占式调度机制
- 采用快速切换机制:对终端具有快速响应能力、快速的任务分派能力
非抢占式调度算法
非抢占式轮转调度算法:
- 响应时间:数秒至数十秒
- 可用于要求不太严格的实时控制系统
非抢占式优先级调度算法:
- 响应时间:数秒至数百毫秒
- 可用于有一定要求的实时控制系统
抢占式调度算法
基于时钟中断的抢占式优先级调度:
- 响应时间:几十毫秒至几毫秒
- 可用于大多数实时系统
立即抢占的优先级调度:
- 响应时间:几毫秒至几百微秒
- 可用于有严格时间要求的实时系统
最早截止时间优先(EDF)调度算法
- EDF根据任务的截止时间确定优先级,截至时间越早,优先级越高
- 既可用于抢占式调度,也可用于非抢占式调度
- 非抢占式调度用于非周期实时任务
- 抢占式调度用于周期实时任务
最低松弛度优先LLF算法
- 根据任务的紧急程度(松弛度)确定任务优先级
- 松弛度越低,优先级越高
- 松弛度=必须完成时间-本身的运行时间-当前时间
- 主要用在抢占式调度方式中
优先级倒置现象
采用优先级调度和抢占方式,可能产生优先级倒置现象:高优先级进程被低优先级进程延迟或阻塞
解决方法:
- 制定一些规定,如规定低优先级进程执行后,其所占用的处理及不允许被抢占
- 建立动态优先级继承
3.4Linux进程调度
默认调度算法:完全公平调度算法CFS算法
基于调度器类:允许不同的可动态添加的调度算法并存,每个类都有一个特定的优先级
- 总调度器:根据调度器类的优先顺序,依次对调度器类中的进程进行调度
- 调度器类:使用所选的调度器类算法(调整策略)进行内部的调度
- 调度器类的默认优先级顺序为:Stop_Task>Real_Time>Fair>Idle_Tasks
普通进程调度:
- 采用SCHED_NORMAL调度策略
- 分配优先级、挑选进程并允许、计算使其运行多久
- CPU运行时间与友好值(-20~+19)有关,数值越低优先级越高
实时进程调度:
- 实时调度的进程比普通进程具有更高的优先级
- SCHED_FIFO:金承若处于可执行状态,就会一直执行,直到它自己被阻塞或主动放弃CPU
- SCHED_RR:与SCHED_FIFO大致相同,只是进程在耗尽其时间片后,不能再执行,而是需要接受CPU的调度
3.5死锁概述
概念
- 死锁(Deadlock):
- 指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态是,若无外力作用,这些进程将永远不能再向前推进
- 一组等待的进程,其中每一个进程都持有资源,并且等待着由这个组中其他进程所持有的资源
- 可重用性资源:一次只能分配给一个进程,不允许多个进程共享,遵循:请求资源、使用资源、释放资源
- 可消耗性资源:由进程动态创建和消耗(进程间通信的消息)
- 可抢占性资源:某进程在获得这类资源后,该资源可以再被其他进程或系统抢占,CPU(处理机)和主存区
- 不可抢占性资源:当系统把这类资源分配给某进程后,不能强行收回,只能在进程用完后自行释放,打印机、磁带机
产生死锁的必要条件
- 互斥:一段时间内某资源只能被一个进程占用
- 请求和保持:一个至少持有一个资源的进程等待获得额外的有其他进程持有的资源
- 不可抢占:一个资源只有当持有它的进程完成任务后,自由的释放
- 循环等待:等待资源的进程之间存在环
死锁原因
- 竞争不可抢占性资源引起死锁
- 竞争可消耗性资源引起死锁
- 进程推进顺序不当引起死锁
处理死锁的方法
确保系统永远不会进入死锁状态
- 死锁预防
- 死锁避免
允许进入死锁状态,然后恢复系统
- 死锁检测
- 死锁恢复
忽略这个问题,假装系统中从未出现过死锁。这个方法被大部分的操作系统采用,包括UNIX
方法:
- 预防死锁:破坏死锁的四个必要条件中一个或几个
- 避免死锁:在资源动态分配是,防止系统进入不安全状态
- 检测死锁:实现不采取任何措施,允许死锁发生,但即使检测死锁发生
- 解除死锁:检测到死锁发生时,采取相应措施,将进程从死锁状态中解脱出来
3.6预防死锁
破坏死锁的四个必要条件中的一个或几个
互斥:
互斥条件是共享资源必须的,不仅不能改变,还应加以保证
请求和保持:
必须帮正进程申请资源的时候没有占用其他资源
- 要求进程在执行前一次性申请全部的资源,只有没有占有资源时才可以分配资源
- 资源利用率低,可能出饥饿
- 改进:进程只获得运行初期所需的资源后,便开始运行;其后台在运行过程中逐步释放已分配的且用毕的全部资源,然后再请求新资源
非抢占:
- 如果一个进程的申请没有实现,它要释放所有占有的资源
- 先占的资源放入进程等待资源列表中
- 进程在重新得到旧的资源的时候可以重新开始
循环等待:
对所有的资源类型排序进行线性排序,并赋予不同的序号,要求进程按照递增顺序申请资源
- 如何规定每种资源的序号是十分重要的
- 限制新类型设备的增加
- 作业使用资源的顺序与系统规定的顺序不同
- 限制用户简单、自主的编程
3.7避免死锁
设一个简单而有效的模型,要求每一个进程声明它所需要的资源的最大数
死锁避免算法动态检查资源分配状态以确保不会出现循环等待的情况
资源分配状态定义为可用的与已分配的资源数,和进程所需的最大资源量
安全状态
- 当进程申请一个有效的资源的时候,系统必须确定分配后是安全的
- 如果存在一个安全序列,则系统处于安全态
- 即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一个进程运行完毕
- 进程序列<P1,P2,...,Pn>是安全的,如果每一个进程Pi所申请的可以被满足的资源数加上其它进程所持有的该资源数小于系统总数。
不安全状态
可能会到达死锁,但不是死锁
安全状态和不安全状态的区别
- 安全状态出发,能保证所有进程都能完成
- 不安全状态出发,无法保证(可能部分完成)
基本事实
- 如果一个系统在安全状态,就没有死锁
- 如果一个系统不是处于安全状态,就有可能死锁
- 死锁避免=>确保系统永远不会进入不安全状态
银行家算法
Dijkstra提出的银行家算法:其这样的名字是由于该算法原本是为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。在OS中也可以用它来实现避免死锁
- 针对资源有多个实例
- 每一个进程必须事先声明使用的最大量
- 当一个进程请求资源,它可能要等待
- 当一个进程得到所有的资源,它必须在有限的时间释放它们
这部分建议去B站找个视频来复习
3.8死锁的检测与解除
当系统为进程分配资源时,若未采取任何限制性措施,则系统必须提供检测和解除死锁的手段,为此,系统必须:
- 保存有关资源的请求和分配信息
- 提供一种算法,以利用这些信息来检测系统是否已经入死锁状态
基本事实
如果图没有环,那么不会有死锁
如果图有环,那么:
- 如果每一种资源类型只有一个实例,那么死锁发生
- 如果一种资源类型有多个实例,那么可能死锁
资源分配图的简化
- 在资源分配图中,找出一个既不阻塞又非独立的进程节点Pi。在顺利的情况下,Pi可获得所需资源而继续运行,直至运行完毕,再释放其所占有的全部资源,这相当于消去Pi所有的请求边和分配边,使之成为孤立的结点
- P1释放资源后,便可使P2获得资源而继续运行,直到P2完成后又释放出它所占有的全部资源
- 在进行一系列的简化后,若能消去图中所有的边,使所有进程都成为孤立结点,则称该图是可完全简化的;若不能,则称其不可完全简化
死锁定理
- 对于较复杂的资源分配图,可能有多个既未阻塞,又非孤立的进程节点,不同的简化顺序,是否会得到不同的简化图?有关文献已经证明,所有的简化顺序,都将得到相同的不简化图
- S为死锁状态的充分必要条件是:当且仅当S状态的资源分配图使不可完全简化的。该充分条件称为死锁定理
死锁的解除
常用解除死锁的两种方法:
- 抢占资源。从一个或多个进程中抢占足够数量的资源给死锁进程,以解除死锁
- 终止或撤销进程。终止系统中一个或多个死锁进程,直到打破循环回路,使死锁状态消除为止。
- 终止所有死锁进程(最简单方法)
- 逐个终止进程(稍温和方法)
进程终止
中断所有的死锁进程
一次中断一个进程,直到死锁环消失
应该选择怎样的中断程序,使“代价最小”?
- 进程的优先级
- 进程需要计算多久,以及需要多久结束
- 进程使用的资源,进程完成还需要多少资源
- 进程是交互的还是批处理的
其他问题
- 通信死锁
- 活锁
- 饥饿
通信死锁
- 竞争性同步:资源死锁
- 多个进程任务无关联,只是共享资源
- 协同同步:通信死锁
- 多个进程共同完成一个任务,无共享资源
- 通信死锁的场景:信息丢失
- 通信死锁的解决:超时重发
活锁
活锁场景:
- 多个礼貌的进程
- 获取资源成功
- 请求新资源失败
- 释放已有资源
- 再次尝试
- 有限的表容量
- 每个进程占有部分
- 试图申请更多资源
饥饿
饥饿场景:
- 打印机分配
- 优先小文件
- 小文件多
- 优先级调度
- 高优先级进程多
解决方案:先来先服务
四、进程同步
4.1进程同步的概念
概念
主要任务:使并发执行的进程之间能有小弟共享资源和相互合作,从而使程序的执行具有可再现性
进程间的制约关系:
- 间接相互制约关系(互斥关系)
- 进程互斥使用临界资源
- 直接相互制约关系(同步关系)
- 进程间相互合作
临界资源:
- 系统中某些资源一次只允许一个进程使用,这样的资源称为临界资源或互斥资源或共享变量
- 诸进程间采取互斥方式,实现了对这种资源的共享
临界区:进程中涉及临界资源的代码段
进入区:用于检查是否可以进入临界区的代码段
退出去:将临界区正被访问的标志恢复为未被访问标志
剩余区:其他代码
同步机制应遵循的准则
- 空闲让进:当无进程处于临界区,应允许一个请求进入临界区的进程立即进入自己的临界区
- 忙则等待:已有进程处于其临界区,其他试图进入临界区的进程必须等待
- 有限等待:等待进入临界区的进程不能“死等”
- 让权等待:不能进入临界区的进程,应释放CPU(如转换到阻塞状态)
进程同步机制
- 软件同步机制:使用编程方法解决临界区问题
- 有难度、具有局限性,现在很少采用
- 硬件同步机制:使用特殊的硬件指令,可有效实现进程互斥
- 信号量机制:一种有效的进程同步机制,已被广泛应用
- 管程机制:新的进程同步机制
4.2软件同步机制
不做介绍
4.3硬件同步机制
关中断:
- 进入锁测试之前关闭终端,完成锁测试并上锁之后才打开中断
- 可有效保证互斥,但存在很多缺点
Test-and=Set指令
Swap指令
缺点:
- 不符合“让权等待”原则,浪费CPU时间
- 很难解决复杂的同步问题
4.4信号量机制 (推荐看B站)
信号量-软件解决方案:
- 保证两个或多个代码段不被并发调用
- 在进入关键代码段前,进程必须获取一个信号量,否则不能运行
- 执行完该关键代码段,必须释放信号量
- 信号量有值,为正说明它空闲,为负说明其忙碌
类型:
- 整型信号量
- 记录型信号量
- AND型信号量
- 信号量集
整型信号量
- 信号量S-整型变量
- 提供两个不可分割的【原子操作】访问信号量(即要么都执行,要么都不执行)
void wait(int s){
while(s<=0){};
s--;
}
void signal(int s){
s++;
}
- Wait(s)又称为P(S)
- Signal又称为V(S)
- 缺点:进程忙等
记录型信号量
每个信号量S除一个整数值S.value外,还有一个进程等待队列S.list,存放则色在该信号量的各个进程PCB
typedef struct {
int value;
Struct process* L;
}semaphore
void wait(semphore S) {
S.value--;
if (S.value < 0) {
block(S.L);
}
}
void signal(semphore S) {
S.value++;
if (S.value <=0) {
wakeup(S.L);
}
}
五、存储器管理
5.1存储器的层次结构
金字塔模型,越高越少,性能越高,价格越贵
概念
- 可执行寄存器:寄存器和主存储器
- 主存储器:内存或主存
- 寄存器:访问速度最快,与CPU协调工作,价格贵
- 高速缓存:介于寄存器和存储器之间
- 备份主存常用数据,减少对主存储器的访问次数
- 缓和内存与处理机之间的矛盾
- 磁盘缓存
- 暂时存放频繁使用的一部分磁盘数据和信息
- 缓和主存和I/O设备在速度上的不匹配
- 利用贮存的部分空间,主存可看成辅存的高速缓存
5.2程序的装入和链接
程序的运行步骤:
- 编译:由编译程序(Compiler)对源程序进行编译,形成若干个目标模块
- 链接:由链接程序(Linker)将目标模块和它们所需要的库函数链接在一起,形成一个完整的装入模块
- 由装入程序(Loader)将装入模块装入内存
物理地址和逻辑地址
物理地址(绝对地址)
- 物理内存的地址,内存以字节为单位编址
- 物理地址空间:所有物理地址的集合
逻辑地址(虚拟地址、相对地址)
- 由CPU产生的地址,即程序编译后使用的相对于0字节的地址
- 逻辑地址空间:由程序所生成的所有逻辑地址的集合
内存保护的实现:硬件
- 基地址寄存器:保存最小的合法物理内存地址(基地址)
- 界限寄存器:保存合法的地址范围大小(界限地址)
- 内存空间保护的实现:判断“基地址<=物理地址<(基地址+界限地址)”是否成立
程序的装入
绝对装入方式:
- 编译时产生的地址使用绝对地址
- 程序或数据被修改时,需要重新编译程序
可重定位装入方式:
- 编译后的目标模块使用相对地址
- 在装入时,完成重定位(静态重定位)
- 需硬件支持
动态运行时装入方式:
- 编译后的目标模块使用相对地址
- 在装入时,完成重定位(动态重定位)
程序的链接
静态链接:
- 在程序运行前,将各目标模块及他们所需的函数链接成一个完成整的装配模块,以后不再拆开
- 对相对地址进行修改;变换外部调用信号
装入时动态链接:
- 在装入内存时,采用边装入边链接的链接方式
- 便于修改和更新
- 便于实现对目标模块的共享
运行时动态链接:
- 将某些目标模块的链接推迟到执行时才执行。即在执行过程中,若发现一个被调用模块尚未装入内存时,立即由OS去找该模块并将它装入内存,并把它连接到调用者模块上
- 加快装入过程,节省大量的内存空间
5.3对换与覆盖
略
5.4连续分配存储管理方式
连续分配方式:为一个用户程序分配一个连续的内存空间。
分类:
- 单一连续分配
- 固定分区分配
- 动态分区分配
- 动态可重定位分区分配
单一连续分配
内存:
- 系统区:供OS使用、低址部分
- 用户去:供用户使用
分配方式:单道程序环境下,金装有一道用户程序,即整个内存的用户空间由改进成独占
- 内存分配管理十分简单,内存利用率低
- 用于单用户、单任务OS
未采取存储器保护措施:节省硬件、方案可行
固定分区分配
- 最早的,也是最简单的一种可运行多道程序的存储管理方式
- 与先把可分配的主存储器空间分割成若干个连续区域,称为一个分区
- 每个分区的大小可以相同也可以不同。但分区大小不变,每个分区装一个且只能装一个作业
- 内存分配:如果有一个空闲区,则分配给进程
动态分区分配
- 又称为可变分区分配,根据进程的实际需要,动态地位置分配内存空间
- 数据结构:表、链
- 分配算法:顺序式、索引式
- 分配操作:分配内存、回收内存
分配算法:
- 基于顺序搜索的动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法、最坏适应算法
- 基于索引搜索的动态分区分配算法:快速适应算法、伙伴系统、哈希算法
快速适应算法:
- 将空闲分区按其容量大小进行分类,具有相同容量的所有空闲分区设有一个空闲分区链表
- 系统设有一张管理索引表,每一项对应一个空闲分区类型
- 分配时,根据进程长度,从索引表中寻找能容纳它的最小空闲分区链表;从链表中取下第一块进行分配
- 特点:
- 优点:不分割分区,不产生碎片,查找效率高
- 缺点:分区归还主存时算法复杂,系统开销较大,存在浪费
伙伴系统:
- 分区大小均为2的k次幂
- 内存按2的幂的大小来分配,如4KB、8KB等
- 满足要求是以2的幂为单位的
- 如果请求不为2的幂,则需要调整到下一个更大的2的幂:先计算一个i值,使2i-1<n<=2i,在2i的空闲区表中找
- 当分配需求小于现在可用内存时,当前段就分为两个更小的2的幂段
- 继续上述操作直到合适的段大小
- 主要用于多处理机系统中(Linux早期版本)
哈希算法:
- 建立哈希函数,构造一张以空闲分区大小为关键字的哈希表,该表的每一个表项对应于一个空闲分区链表的头指针
- 进行分配时,根据空闲区大小,通过计算哈希函数,得到在哈希表中的位置,找到对应的空闲分区链表
- 优点:查找快速
动态可重定位分区分配
- 连续分配存在的问题
- 碎片:不能被利用的小分区
- 解决方案:紧凑,要求代码和数据可以在内存中移动
- 紧凑:通过移动内存中的作业位置,以把原来多个分散的小分区拼接成一个大分区的方法,也叫“拼接”
- 动态重定位:在指令运行时,实现地址转换(相对地址转换为绝对地址)
- 分配算法:类似于动态分区分配算法,增加了紧凑的功能
5.5分页存储管理方式
- 进程的逻辑空间可能是不连续的,如果有可用的物理内存,它将分给进程
- 把物理内存分成大小固定的块,称为物理块(frame)。(大小为2的幂,通常为1KB~8KB)
- 把逻辑内存也分成固定大小的块,称为页(page)
- 保留所有空闲块的记录
- 运行一个有N页大小的程序,需要找到N个空的页框来装入程序
- 存在页内碎片:进程最后一页经常装不满,而形成不可利用的碎片
页表
- 系统为每个进程建立了一张页表
- 逻辑地址空间内所有页,一次在页表中有一表项,记录相应页在内存中对应的物理块号
- 页表的作用:实现从页号到块号的地址映射
页表的实现
- 页表被保存在主存中
- 页表寄存器(PTR)指向页表的起始地址和长度
- 在这个机制中,每一次的数据/指令存取需要两次内存访问,一次是访问页表,一次是访问数据/指令
- 解决两次访问的问题,是采用小但专用且快速的硬件缓冲,这种缓冲称为转换表缓冲器(TLB)或联想寄存器
页表结构
现代的大多数计算机系统,都支持非常大的逻辑地址空间。在这样的环境下,页表就变得非常大,要占用相当大的空间。
解决方法:
- 对页表所需要的内存空间,采用离散分配方式
- 部分页表调入内存
页表结构:两级页表、多级页表、反置页表
5.6分段存储管理方式
略
六、虚拟存储器
6.1虚拟存储器概述
前面所介绍的各种存储器管理方式,有一个共同特点:作业全部装入内存后才能运行
问题:
- 大作业装不下
- 少量作业得以运行
解决方法:
- 扩充内存
- 逻辑上扩充内存容量(虚拟存储器)
虚拟存储器定义
基于局部性原理,应用程序在运行之前,没有必要全部装入内存,仅需将那些当前要运行的部分页面或段先装入内存便可运行,其余部分暂留在盘上
虚拟存储器:具有请求调度功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统
其逻辑容量由内存容量和外存容量之和所决定,其运行速度接近于内存速度,而成本接近于外存
虚拟存储器的特征
- 多次性:作业中的程序和数据允许被分成多次调入内存
- 对换性:作业运行时无需常驻内存
- 虚拟性:从逻辑上扩充了内存容量,使用户看到的内存容量远大于实际内存容量
虚拟存储器的实现方法
请求分页系统:
- 硬件支持:页表、缺页中断、地址变换机构
- 软件支持:请求调页软件、页面置换软件
请求分段系统:
- 硬件支持:段表、缺段中断、地址变换机构
- 软件支持:请求调段软件、段置换软件
段页式虚拟存储器:
- 增加请求调页和页面置换
- Intel 80386及以后
6.2请求分页存储管理方式
请求分页中的硬件支持
请求页表机制、缺页中断机构、地址变换机构
请求页表机制:
- 状态为:指示该页是否在内存
- 访问字段:记录该页在一段时间内被访问的次数
- 修改位:标志该页是否被修改过
- 外村地址:指示该页在外存中的地址(物理块号)
缺页中断机构:
- 在指令执行期间产生和处理中断信号
- 一条指令在执行期间,可能产生多次缺页中断
地址变换机构:与分页内存管理方式类似
请求分页中的内存分配
最小物理块数的确定:保证进程正常运行所需的最小物理块数
物理块的分配策略:
- 固定分配 局部置换
- 可变分配 全局置换
- 可变分配 局部置换
物理块分配算法:
- 平均分配算法
- 按比例分配算法
- 考虑优先权的分配算法
页面调入策略
何时调入页面:
- 预调页策略:预先调入一些页面到内存
- 请求调页策略:发现需要访问的页面不在内存是,调入内存
从何处调入页面:
- 如系统拥有足够的对换区空间,全部从对换区调入所需页面
- 如系统缺少足够的对换区空间,凡是不会被修改的文件,都直接从文件区调入;当换出这些页面时,由于未被修改而不必将它们重写磁盘,以后再调入时,仍从文件区直接调入
- UNIX方式:未运行过的页面,从文件区调入;曾经运行过但又被换出的页面,从对换区调入
页面调入方法
- 查找所需页在磁盘上的位置
- 查找一内存空闲块:
- 如果有空闲块,就直接使用
- 如果没有空闲块,使用页面置换算法选择一个“牺牲“内存块
- 将牺牲内存块的内容写到磁盘上,更新页表和物理块表
- 将所需页读入空闲块,更新页表
- 重启用户进程
6.3页面置换算法
种类
- 最佳置换算法(OPT)
- 先进先出置换算法(FIFO)
- 最近最久未使用置换算法(LRU)
- 最少使用算法(LFU)
- Clock置换算法
- 页面缓冲算法PBA
需要一个最小的缺页率
通过运行一个内存访问的特殊序列(访问序列),计算这个序列的缺页次数
最佳置换算法(OPT)
被置换的页将是之后最长时间不被使用的页
由于需要预知未来,因此无法实现,但可以用来作为置换算法的性能评价依据。
先进先出置换算法(FIFO)
思路:总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰
实现简单,性能较差,因为调出的页可能是经常访问的。很少单独使用
最近最久未使用置换算法(LRU)
核心思想:根据历史预测未来
LRU算法的硬件支持:寄存器、栈
寄存器:为内存中的每个页面设置一个移位寄存器
- 被访问的页面对应寄存器的Rn-1位置为1,定时右移
- 具有最小数值的寄存器所对应的页面为淘汰页
栈:保存当前使用的各个页面的页面号
- 被访问的页,移到栈顶
- 栈底时最近最久未使用页面的页面号
这种方法是最优置换算法的一种近似,但开销比较大
最少使用算法(LFU)
为内存中的每个页面设置一个移位寄存器,用来记录该页面的被访问频率
思路:缺页时,置换访问次数最少的页面
特征:
- 开销较大
- 开始时频繁使用,但以后不使用的页面很难置换
- 解决方法:计数定期右移
Clock置换算法
简单的Clock算法
- 每个页都与一个访问位相关联,初始值为0
- 当页被访问时访问位为1
- 置换时选择访问位为0的页;若为1,重新置为0
改进型Clock算法
- 除需考虑页面的使用情况外,还需增加置换代价
- 淘汰时,同时检查访问位A与修改位M
- A=0,M=0:最佳淘汰页
- A=0,M=1
- A=1,M=0
- A=1,M=1:最坏淘汰页
- 置换时,循环一次查找第一类、第二类页面,找到为止
页面缓冲算法PBA
影响效率的因素:页面置换算法、写回磁盘的频率、读入内存的频率
目的:
- 显著降低页面换进、换出的频率,减少了开销
- 可采用较简单的置换策略,如不需要硬件支持
具体做法:设置两个链表
- 空闲页面链表:保存空闲物理块
- 修改页面链表:保存已修改且需要被换出的页面等被换出的页面数目到达一定值时,再一起换出外存
6.4抖动与工作集
抖动:一个进程的页面经常换入换出
如果一个进程没有足够的页,那么缺页率将很高,将导致:
- CPU利用率低下
- 操作系统任务需要增加多道程序设计的道数
- 系统中将加入一个新的进程
产生抖动的原因
根本原因:
- 同时在系统中运行的进程太多
- 同时分配给每一个进程的物理块太少,不能满足进程运行的基本要求,致使进程在运行时,频繁换页,必须请求系统将所缺页面调入内存
抖动的发生与系统为进程分配物理块的多少有关
工作集
所谓工作集,时指在某段时间间隔t里进程是既要访问页面的集合,用表示,属于.
工作集的变化:
- 进程开始执行后,随着访问新页面逐步建立比较稳定的工作集
- 当内存访问的局部性区域位置大致稳定时,工作及大小也大致稳定
- 局部性区域的位置变化时,工作集快速扩张和收缩过度到下一个稳定值
抖动的预防方法
采取局部置换策略:只能在分配给自己的空间内进行置换
把工作集算法融入到处理机调度中
利用L=S准则调节缺页率:
- L是缺页之间的平均时间
- S是平均却页服务时间
- L>S说明很少发生缺页
- L<S说明频繁缺页
- L=S磁盘和处理机都可达到最大利用率
选择暂停进程
6.5请求分段存储管理方式
略
七、输入/输出系统
7.1I/O系统的功能、模型和接口
I/O系统管理的主要对象:I/O设备和对应的设备控制器
I/O系统的主要任务:完成用户提出的I/O请求,提高I/O速率和设备利用率
I/O系统的基本功能
- 能够隐藏物理设备的细节
- 能够保证OS与设备无关
- 能够提高处理机和I/O设备的利用率
- 能够对I/O设备进行控制
- 能够确保对设备的正确共享
- 能够处理错误
各种I/O模块之间的关系
I/O系统的上下接口:
- 上接口:I/O系统接口
- 下接口:软件/硬件接口
- 在上、下接口之间是I/O系统
I/O系统的分层:
- 中断处理程序
- 设备驱动程序
- 与设备无关的I/O软件
I/O系统接口
块设备接口:
- 块设备:数据的存取和传输都是以数据块为单位的设备,如磁盘,光盘,通常采用DMA I/O方式
- 隐藏了磁盘的二维结构
- 将抽象命令映射为底层操作
流设备(字符设备)接口:
- 字符设备:数据的存取和传输都是以字符为单位的设备,如键盘,打印机。不可寻址
- 通常采用中断驱动I/O方式
- get和put操作:字符设备采用顺序存取方式
- in-control指令:包含许多参数,每个参数均表示一个与具体设备相关的特定功能
网络通信接口:
- OS提供相应的网络软件和网络通信接口,以使计算机能通过网络同网络上的其他计算机进行通信
7.2I/O设备和设备控制器
I/O设备的类型
- 按使用特性分类:存储设备、I/O设备
- 按传输速率分类:
- 低速:键盘、鼠标等
- 中速:行式打印机等
- 高速 :磁带机、磁盘机
- 按信息交换单位分类:块设备、字符设备
- 按设备的共享属性分类:独占设备、共享设备
设备与控制器之间的接口
通常,设备并不是直接与CPU进行通信,而是与设备控制器通信,因此,在设备与设备控制器之间应有一接口,在该接口中有三类信号个对应一条信号线,分别是:数据、状态、控制信号线。
设备控制器
- 主要功能:控制一个或多个I/O设备,以实现I/O设备和计算机之间的数据交换
- 是CPU与I/O设备之间的接口,接受CPU的命令,控制I/O设备工作
- 是一个可编制的设备:
- 当仅控制一个设备时,只有唯一地址
- 当控制多个设备时,有多个地址,并每一个地址对应一个设备
基本功能:
- 接受和识别命令
- 数据交换
- 标识和报告设备的状态
- 地址识别
- 数据缓冲区
- 差错控制
设备控制器的组成:
- 设备控制器与处理机的接口:实现CPU与设备控制器之间的通信,包括数据、地址和控制线
- 与设备的接口:连接设备
- I/O逻辑:实现对设备的控制
内存映像I/O
驱动程序将抽象I/O命令转换成具体的命令和参数等装入设备控制器的相应寄存器,由控制器执行这些命令,具体实施对I/O设备的控制。具体方法:
- 采用特定I/O指令:访问内存和设备需要两种不同的指令
- 采用内存映像I/O形式:在编址上不再区分内存单元地址和设备控制器中的寄存器地址,统一编址k。k在0~n-1范围时,为内存地址;若k>=n时,为某控制器的寄存器地址。统一了访问方法,简化了I/O编程
I/O通道
I/O通道的引入:
目的:使一些原来由CPU处理的I/O任务转由通道来承担,从而把CPU从繁杂的I/O任务中解脱出来。
通道是特殊处理机,与普通处理机的区别:指令类型单一、没有自己的内存(与CPU共享内存)
通道类型:
- 字节多路通道:按字节交叉方式工作的通道
- 数组选择通道:可以连接多台高速设备,但在一段时间内只允许一台设备传输数据,传输率高
- 数组多路通道:结合前两者优点,含有多个非分配型子通道
“瓶颈”问题:通道价格昂贵,造成通道不足。
解决方法:增加设备到CPU间的通路而不增加通道
多路方式不仅解决了“瓶颈”问题,而且提高了系统的可靠性
I/O设备的控制方式
- 用轮询的可编程I/O方式(基本不用):
- 实现容易但效率偏低,CPU会长期处于忙等
- 使用中断的可编程I/O方式(广泛采用):
- 当某进程要启动某个I/O设备工作时,便由CPU向相应的设备控制器发出一条I/O命令,然后立即返回继续执行原来的任务。设备控制器域是按照命令的要求去控制指令的I/O设备。此时,CPU与I/O设备并行操作
- 直接存储器访问方式(DMA):进一步减少CPU对I/O设备的干预
- 数据传输的基本单位是数据块
- 所传送的数据是从I/O设备直接送入内存的,或者相反
- 仅在传送一个或多个数据块的开始和结束时,才需CPU干预
- I/O通道方式:是DMA方式的发展,可进一步减少CPU的干预
- 是对一组数据快以读/写及有关的控制和管理作为单位干预
- 可实现CPU、通道和I/O设备三者的并行操作
- 通道程序:由一系列通道指令构成,通道指令不同于CPU指令
7.3中断和中断处理程序
介绍
中断和陷入:
- 中断:CPU对I/O设备发来的中断信号的一种响应
- 陷入:CPU内部事件引起的中断
中断向量表:存放每个设备的中断处理程序的入口地址,并为每个设备的中断请求作为一个中断号,对应于中断向量表中的一个表项
中断优先级:系统为每个中断源规定不同的优先级
对多中断的处理方式
当处理及正在处理一个中断时,又来了一个新的中断请求,有两种处理方式:
- 屏蔽(禁止)中断
- 嵌套中断
Linux中的中断处理
采用了上半部和下半部机制:
- 上半部:中断处理程序。(简单快速,执行时禁止一些或全部中断)
- 下半部:一些虽然与中断有关但是可以延后执行的任务(稍后执行,执行时可以响应所有的中断)
中断处理程序的设计:
- 注册中断
- 处理中断
- 注销中断
7.4设备驱动程序
略
7.5与设备无关的I/O软件
略
7.6用户层的I/O软件
略
7.7缓冲区管理
缓冲区是一个存储区域,可以由专门的硬件组成;更多的是利用内存。
引入缓冲区的原因:
- 缓和CPU与I/O设备间速度不匹配的矛盾
- 减少对CPU的中断频率,放宽对CPU中断响应时间的限制
- 解决数据粒度不匹配的问题
- 提高CPU与I/O设备之间的并行性
单缓冲
每当用户进程发出一I/O请求时,操作系统便在主存中位置分配一缓冲区
在设备输入时
- T:从磁盘把一块数据输入到缓冲区的时间
- M:操作系统将该缓冲区中的数据送到工作区的时间
- C:CPU对这块数据处理的时间
- 当T>C,系统对每一块数据的处理时间为M+T(C忽略)
- 反之,则为M+C
- 系统对每一块数据的处理时间为:Max(C,T)+M
双缓冲
- 在设备输入时,先将数据送入第一缓冲区,装满后便转向第二缓冲区
- 此时操作系统可以从第一缓冲区移出数据,并送入用户进程,接着由CPU对数据进行计算
- 在双缓冲时,系统处理一块数据的时间可以粗略地认为是Max(C,T),如果C>T,则可使CPU不必等待设备输入
环形缓冲区
当输入和输出两者的速度相差悬殊,双缓冲的效果则不够理想,不过可以随着缓冲区数量的增加,使情况有所改善。
多个缓冲区:
- 在循环缓冲中包含多个缓冲区,其每个缓冲区的大小相同
- 作为输入的多缓冲区可分为三类:
- 用于装输入数据得空缓冲区R
- 已装满数据的缓冲区G
- 计算进程正在使用的现行工作缓冲区C
- 多个指针:
- 作为输入的缓冲区可设置3个指针:
- 用于指示及算您成下一个而用缓冲区G的指针Nextg
- 指示输入进程下次可用的空缓冲区R的指针Nexti
- 用于指示计算进程正在使用的缓冲区C的指针Current
- 作为输入的缓冲区可设置3个指针:
缓冲池
当系统较大时,将会有许多循环缓冲,这不仅要消耗大量的内存,且利用率不高。
为了提高缓冲区利用率,引入公共缓冲池,在池中设置了多个可供若干个进程共享的缓冲区
缓冲池的组成:
- 空闲缓冲队列:空闲缓冲区所链城的队列
- 输入队列:装满输入数据的缓冲区所链成的队列
- 输出队列:装满输出数据的缓冲区所链成的队列
- 4中工作缓冲区:收容输入、提取输出、收容输出、提取输入缓冲区
缓存和缓冲
- 缓冲可以保存数据项的唯一的现有版本
- 缓存指示提供一个位于其他地方的数据项的更快存储副本
- 有时,同一个内存区,既可以是缓冲,也可以是缓存
7.8磁盘性能概述和磁盘调度
磁盘结构
- 盘面(磁头):磁盘设备可能包含一个或多个盘片,每个盘片分为一个或两个盘面,每个面上有一个读写磁头
- 磁道(柱面):每个盘面可分为若干磁道
- 扇区:每条磁道逻辑上分成若干大小相同的扇区。每个扇区的大小相当于一个盘块(数据块)
- 每条磁道上可存储相同数目的二进制位
- 磁盘密度即每英寸中所存储的位数,显然是内层磁道叫外层磁道的密度高
容量=柱面*磁头*扇区
磁盘的类型
分类一:硬盘、软盘
分类二:单片盘、多片盘
分类三:
- 固定头:每个磁道上都有一个读写磁头
- 并行方式读/写,有效提高I/O速度
- 主要用于大容量磁盘
- 移动头:每个盘面仅有一个磁头,能移动寻道
- 串行方式读/写,I/O速度较慢
- 广泛应用于中、小磁盘设备中
磁盘访问时间
磁盘在工作时是以恒定速率旋转
为了读写:
- 磁头必须移动到要求的磁道上
- 等待所制定的山区开始位置旋转到磁头下
- 开始读写数据
磁盘的访问时间=寻道时间+旋转延迟时间+传输时间
早期的磁盘调度算法
磁盘调度的目标, 使使磁盘的平均寻道时间最小
- 先来先服务FCFS
- 最短寻道时间优先SSTF
- SCAN算法
- 循环扫描算法C-SCAN
- CLOCK
- NStepSCAN算法
- FSCAN算法
先来先服务FCFS调度算法
最简单的磁盘调度算法,但平均寻道时间可能较长
最短寻道时间优先SSTF
选择这样的进程,其要求访问的磁道,与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,但不保证平均寻道时间最短(贪心算法)
SSTF明显优于FCFS,但可能会出现饥饿
SCAN算法
也称:电梯调度算法。不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头当前的移动方向
磁臂从磁盘的一段向另一端移动,沿途响应服务请求,当到达另一端是,磁头改变移动方向,继续处理。磁头在磁盘上来回扫描
循环扫描算法C-SCAN
提供比SCAN算法更均匀的等待时间
磁头从磁盘一端移动到另一端,随着移动不断处理请求。不过,当磁头移动到另一端时,马上返回到磁盘开始,返回时并不处理请求。
CLOCK
C-SCAN的一种形式。磁头之移动到一个方向上最远的请求位置。戒指,马上回头,而不是继续道磁盘的尽头
NStepSCAN算法
“磁臂粘着”现象:进程反复请求对某一磁道的I/O操作
将磁盘请求队列分为若干个长度为N的子队列;按FCFS算法依次处理子队列;每个子队列使用SCAN算法
FSCAN算法
是 NStepSCAN算法的简化:
请求队列分为两个子队列:
- 当前所有请求队列,按SCAN算法调度
- 扫描期间,新出现的请求队列,推迟到下一次扫描时处理
八、文件管理
8.1文件和文件系统
数据项、记录和文件
数据项:
- 基本数据项:描述一个对象的某种属性,又称字段
- 组合数据项:由若干个基本数据项组成
记录:
- 记录时一组相关数据项的集合,用于描述一个对象在某方面的属性
- 关键字:唯一能表示一个记录的数据项
- 如;学号、学号+课程号
文件:具有文件名的一组相关元素的集合
- 有结构文件(记录)、无结构文件(字符流)
- 在文件系统中温嘉三年hi最大的单位,描述了一个对象集
文件类型
按用途分类:
- 系统文件
- 用户文件
- 库文件
按文件中数据的形式分类:
- 源文件
- 目标文件
- 可执行文件
按存取控制属性分类:
- 只执行文件
- 只读文件
- 读写文件
按组织形式和处理方式分类:
- 普通文件
- 目录文件
- 特殊文件
文件系统的层次结构
对象及其属性
- 对象:文件、目录、磁盘存储空间
对对象操纵和管理的软件集合
- 文件管理系统的核心部分
文件系统的接口
- 命令接口
- 程序接口
文件系统的功能
- 对文件存储空间的管理
- 对文件目录的管理
- 用于将文件的逻辑地址转换为物理地址的机制
- 对文件读和写的管理
- 对文件的共享和保护
与文件系统有关的软件
- I/O控制层:文件系统最底层,设备驱动程序层
- 基本文件系统层:处理内存与磁盘之间数据块的交换
- 基本I/O管理程序:完成与磁盘I/O有关的事物
- 逻辑文件系统:处理与记录和文件相关的操作
文件操作
最基本的文件操作:
- 创建文件、删除文件、读文件、写文件
- 设置文件的读/写位置
文件的打开和关闭操作:
- 打开:系统将文件从外存拷贝到内存打开文件表的一个表目中
- 关闭:把文件从打开文件表的表目中删除
其他文件操作:
- 重命名、改文件拥有者、查询文件状态等
- 创建/删除目录
8.2文件的逻辑结构
文件结构
- 文件的逻辑结构:从用户观点所观察的文件组织形式
- 文件的物理结构:文件的存储结构,指系统将文件存储在外村上所形成的一种存储组织形式
- 不仅与存储介质的存储性能有关
- 也与所采用的外村分配方式有关
文件的逻辑结构和物理结构,都影响文件的检索速度
文件名和文件类型
按文件是否有结构分类:
- 有结构文件(记录式文件)
- 定长记录
- 变长记录
- 无结构文件(流式文件)
- 源程序、可执行文件、库函数
有结构文件按文件的记录方式分类:
- 顺序文件
- 索引文件
- 索引顺序文件
顺序文件
串结构:按存入时间的先后顺序,记录间的顺序与关键字无关,但检索比较费时
顺序结构:指定一个字段为关键字,所有记录按关键字排序。检索时可用有效的查找算法。
优点:有利于大批记录读写、存取效率最高、可存储在顺序存储设备上
缺点:增删改查效果差
索引文件
按关键字建立索引:
- 为边长记录文件建立一张索引表
- 索引表按关键字排序
- 实现直接存取
具有多个索引表的索引文件:
- 为顺序文件建立多个索引表
- 为每一个可能会成为索引条件的域配置一张索引表
顺序索引文件
- 有效克服了变长记录文件不便于直接存取的缺点
- 保留了顺序文件的关键特征:记录按关键字的顺序组织
- 新增了2个新特征:
- 引入文件索引表:实现随机访问
- 增加溢出文件:记录新增、删除和修改的记录