第一章 计算机系统概述
1.1基本概念
1.1.1操作系统的基本概念
- 概念定义
- 负责管理协调硬件、软件等计算机资源工作
- 为上层用户、应用程序提供简单易用的服务
- 是一种系统软件
- 功能和目标
- 资源管理者
- 处理机管理
- 存储器管理
- 文件管理
- 设备管理
- 向用户提供服务
- 命令接口
- 联机命令接口
- 脱机命令接口
- 程序接口:由一组系统调用(广义指令)组成
- GUI用户图形界面
- 对硬件机进行扩展 :扩充机器
- 资源管理者
1.1.2特征
- 并发
- 共享
- 互斥共享
- 同时共享
- 虚拟
- 空分复用技术(虚拟存储技术)
- 时分复用技术(虚拟处理机技术)
- 异步
注意并发和并行的区别。
并发和共享是操作系统两个最基本的特征,两者之间互为存在的条件:①资源共享是以程序的并发为条件的,若系统不允许程序并发执行,则自然不存在资源共享问题;②若系统不能对资源共享实施有效的管理,则必将影响到程序的并发执行,甚至根本无法并发执行。
1.2操作系统发展历程
- 手工操作阶段:缺点:人机速度矛盾
- 批处理阶段
- 单道批处理系统
- 优点:一定程度上缓解了人机速度矛盾
- 缺点:资源利用率还是很低
- 多道批处理系统(操作系统开始出现
- 优点:多道程序并发执行,资源利用率高
- 缺点:不提供人机交互功能
- 单道批处理系统
- 分时操作系统
- 优点:提供人机交互功能
- 缺点:不能优先处理紧急任务
- 实时操作系统
- 硬实时操作系统:必须在严格的规定时间内完成处理
- 软实时操作系统:能接受偶尔违法规定时间
- 优点:可靠性,及时性(能优先处理紧急任务
- 网络操作系统
- 分布式操作系统
- 个人计算机操作系统
1.3操作系统运行环境
操作系统运行机制和体系机构
- 运行机制
- 两种指令
- 特权指令
- 非特权指令
- 两种处理机状态
- 核心态
- 用户态
- 两种程序
- 内核程序
- 应用程序
- 两种指令
- 操作系统内核
- 时钟管理:实现计时功能
- 中断处理:负责中断机制
- 原语:
- 是一种特殊的程序
- 处于操作系统最底层,是最接近硬件的部分
- 原子性:运行一气呵成,不可中断
- 运行时间较短,调用频繁
- 对系统资源进行管理的功能
- 进程管理
- 存储器管理
- 设备管理
- 体系结构
- 大内核
- 优点:高性能
- 缺点:内核代码庞大,结构混乱,难以维护
- 微内核
- 优点:内核功能少,结构清晰,方便维护
- 缺点:需要频繁地在核心态和用户态直接切换,性能低
- 大内核
- 特权指令只能在核心态下执行
- 内核程序只能在核心态下执行
- 用户态到核心态是通过中断实现的,而且中断时唯一途径
- 访管指令是非特权指令,是核心态唯一不执行的指令
1.3.2中断与异常
- 中断机制的产生:为了实现多道程序并发执行而引入的一种技术
- 中断的概念和作用:
- 发生中断,就意味着需要操作系统进入开展工作,CPU 会立即进入核心态
- “中断”是CPU 从用户态进入核心态的唯一途径
- 中断的分类:
- 内中断(异常、例外,陷入)
- 自愿中断–指令中断,如访管指令trap
- 强迫中断
- 硬件故障,如缺页
- 软件中断,如整数除0
- 外中断(狭义上的中断)
- 外设请求,如I/O操作完成后发出的中断信号
- 人工干预,如用户强行终止一个进程
- 内中断(异常、例外,陷入)
- 补充:内中断的另一种分类方式
- 陷阱、陷入(trap):有意为之的异常,如系统调用
- 故障(fault):由错误条件引起的,可能被故障处理程序修复,如缺页
- 中止(abort):不可恢复的致命错误造成的结果,不再返回应用程序
- 外中断的处理过程
- 每条指令执行结束后,CPU 检查是否有外部中断信号
- 如果有外部中断信号,则需要保护被中断进程的CPU 环境
- 根据中断信号类型转入相应的中断处理程序
- 恢复原进程的CPU 环境并退出,返回原程序继续往下执行
1.3.3系统调用
功能分类
- 设备管理:完成设备的请求/释放/启动等功能
- 文件管理:完成文件的读/写/创建/删除等功能
- 进程管理:完成进程的创建/撤销/阻塞/唤醒等功能
- 进程通信:完成进程之间的消息传递/信号传递等功能
- 内存管理:完成内存的分配/回收等功能
1.4操作系统结构
- 分层法
- 定义:将操作系统分为若干层,最底层硬件,最高层为用户接口
- 优点
- 便于系统调试验证,简化系统的设计实现
- 易扩充和易维护
- 缺点
- 合理定义各层比较难,依赖关系固定后不够灵活
- 效率较差
- 模块化
- 定义:将操作系统按功能划分为若干具有一定独立性的模块
- 标准
- 内聚性,模块内部联系紧密度:越高越好
- 耦合度,模块间相互联系程度:越低越好
- 优点
- 提高了操作系统设计的正确性、可理解性和可维护性
- 增强了操作系统的可适应性
- 加速了操作系统的开发过程
- 缺点
- 模块间的接口规定很难满足对接口的实际需求
- 各模块齐头并进,无法找到一个可靠的决定顺序
- 宏内核
- 定义:将系统的主要功能模块都作为一个紧密联系的整体运行在核心态
- 优点:各模块之间共享信息,能有效利用相互之间的有效特性,具有无可比拟的性能优势
- 缺点:随着操作系统需要提供的服务越来越复杂,操作系统的设计规模急剧增长
- 微内核
- 定义:将内核中最基本的功能保留在内核,而将那些不需要在核心态执行的功能移动到用户态
- 基本核心功能
- 与硬件处理紧密相关的部分
- 一些较基本的功能
- 客户和服务器之间的通信
- 基本功能
- 进程(线程)管理
- 低级存储器管理
- 中断和陷入处理
- 特点
- 扩展性和灵活性
- 可靠性和安全性
- 可移植性
- 分布式计算
- 外核
- 策略:对机器进行分区
- 任务:为虚拟机分配资源,并检查使用这些资源的意图
- 优点
- 减少了映射层
- 将多道程序(在外核内)与用户操作系统代码(在用户空间内)加以分离
1.5操作系统引导
引导过程
①激活CPU。激活的CPU读取ROM中的 boot程序,将指令寄存器置为BIOS(基本输入/输出系统)的第一条指令,即开始执行BIOS的指令。
②硬件自检。启动BIOS程序后,先进行硬件自检,检查硬件是否出现故障。如有故障,主板会发出不同含义的蜂鸣,启动中止;如无故障,屏幕会显示CPU、内存、硬盘等信息。
③加载带有操作系统的硬盘。硬件自检后,BIOS开始读取Boot Sequence(通过CMOS里保存的启动顺序,或者通过与用户交互的方式),把控制权交给启动顺序排在第一位的存储设备,然后CPU将该存储设备引导扇区的内容加载到内存中。
④加载主引导记录MBR。硬盘以特定的标识符区分引导硬盘和非引导硬盘。如果发现一个存储设备不是可引导盘,就检查下一个存储设备。如无其他启动设备,就会死机。主引导记录MBR的作用是告诉CPU去硬盘的哪个主分区去找操作系统。
⑤扫描硬盘分区表,并加载硬盘活动分区。MBR包含硬盘分区表,硬盘分区表以特定的标识符区分活动分区和非活动分区。主引导记录扫描硬盘分区表,进而识别含有操作系统的硬盘分区(活动分区)。找到硬盘活动分区后,开始加载硬盘活动分区,将控制权交给活动分区。
⑥加载分区引导记录PBR。读取活动分区的第一个扇区,这个扇区称为分区引导记录(PBR),其作用是寻找并激活分区根目录下用于引导操作系统的程序(启动管理器)。
⑦加载启动管理器。分区引导记录搜索活动分区中的启动管理器,加载启动管理器。
⑧加载操作系统。
1.6虚拟机
- 第一类虚拟机管理程序
- 第二类虚拟机管理程序
第二章 进程和线程
2.1进程和线程
2.1.1进程概念
- 定义:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位
- 组成
- PCB
- 进程描述信息
- 进程标识符PID
- 用户标识符UID
- 进程控制和管理信息
- 进程当前状态
- 进程优先级
- …
- 资源分配清单
- 程序段指针
- 数据段指针
- 键盘&鼠标
- …
- 处理机相关信息:各种寄存器值
- 进程描述信息
- 程序段:存放要执行的代码
- 数据段:存放程序运行过程中处理的各种数据
- PCB
- 组织形式
- 链接方式:按照进程将PCB分为多个队列
- 索引方式:按照进程状态建立索引表,各表项指向PCB
- 特征
- 动态性:进程基本的特征
- 并发性:内存中有多个进程实体,各进程可并发执行
- 独立性:进程是系统进行资源分配和调度的独立单位
- 异步性:各进程以不可知的速度向前推进可能导致运行结果的不确定性
- 结构性:结构上看,进程都有程序段、数据段和PCB组成
2.1.2进程状态和转换
- 状态
- 运行状态:CPU :√, 资源:√
- 就绪状态:CPU :×, 资源:√
- 阻塞状态:CPU :×, 资源:×
- 创建状态:操作系统为新进程非陪资源,创建PCB
- 终止状态:操作系统回收进程资源,撤销PCB
- 转换
- 就绪态 → \rightarrow → 运行态:进程被调度
- 运行态 → \rightarrow → 就绪态:时间片到,或CPU 被其他高优先级的进程抢占
- 运行态 → \rightarrow → 阻塞态:等待系统资源分配,或等待某时间的发生(主动行为)
- 阻塞态 → \rightarrow → 就绪态:资源分配到位,等待事件的发生(被动行为)
- 创建态 → \rightarrow → 就绪态:系统完成创建进程的相关工作
- 运行态 → \rightarrow → 终止态:进程运行结束,或运行过程遇到不可恢复的错误
2.1.4进程控制
基本概念 { 功能:对系统所有进程实施有效管理,具有创建、终止、阻塞、唤醒、切换的功能 实现:用原语实现 基本概念\left\{\begin{aligned} &功能:对系统所有进程实施有效管理,具有创建、终止、阻塞、唤醒、切换的功能\\ &实现:用原语实现\\ \end{aligned}\right. 基本概念{功能:对系统所有进程实施有效管理,具有创建、终止、阻塞、唤醒、切换的功能实现:用原语实现
- 创建
- 原语
- 申请空白PCB
- 为新进程分配所需资源
- 初始化PCB
- 将PCB插入就绪队列
- 事件
- 用户登录:分时系统中,用户成功登录,系统会为其建立一个新的进程
- 作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
- 提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求
- 应用请求:由用户进程主动请求创建一个子进程
- 原语
- 终止
- 原语
- 从PCB集合中找到终止进程的PCB
- 若进程正常运行,立即剥夺CPU ,将CPU 分配给其他进程
- 终止其所有子进程
- 将该进程拥有的资源全部归还给父进程或者操作系统
- 删除PCB
- 事件
- 正常结束
- 异常结束
- 外界干预
- 原语
- 阻塞
- 原语
- 找到要阻塞的进程对应的PCB
- 保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂停其运行
- 将PCB插入对应事件的等待队列
- 事件
- 需要等待系统分配某种资源
- 需要等待相互配合的其他进程完成工作
- 原语
- 唤醒
- 原语
- 再事件等待队列中找到PCB
- 将PCB从等待队列移除,设置进程为就绪态
- 将PCB插入就绪队列,等待被调度
- 事件:等待事件的发生
- 原语
- 切换
- 原语
- 将运行环境信息装入PCB
- 将PCB移入相应队列
- 选择另一个进程执行,并更新其PCB
- 根据PCB恢复新进程所需的运行环境
- 事件
- 当前进程时间片到
- 有更高级的进程到达
- 当前进程主动阻塞
- 当前进程终止
- 原语
2.1.5进程通信
- 共享存储
- 设置一个共享空间
- 要互斥地访问共享空间
- 方式
- 低级:基于数据结构
- 高级:基于存储区
- 消息传递
- 传递结构化的消息
- 系统提供“发送/接受 原语”
- 通信方式
- 直接:消息直接挂在接收方的消息队列
- 间接:消息先发送到中间体(信箱)
- 管道通信
- 设置一个共享文件(管道,即缓冲区)
- 一个管道只能实现半双工通信
- 实现双向同时通信需要建立两个管道
- 各进程互斥访问管道
- 写满时不能再写,读空时不能再读
- 没写满不能读,没读空不能写
2.1.6线程和多线程
- 线程概念和作用
- 概念:可理解为“轻量级进程”
- 作用:增加并发度,减少并发带来的开销
- 引入后的变化
- 资源分配
- 处理机调度
- (实现并发的)系统开销
- 属性
- 线程时处理机调度的单位,进程是资源分配的单位
- 同一进程的各线程共享进程拥有的资源
- 同一进程内的线程切换不会导致进程切换
- 多CPU 计算机中,各个线程占用不同大的CPU
- 每个线程都有一个ID,线程控制块(TCB)
- 线程也有就绪、阻塞、运行三种基本状态
- 线程几乎不拥有系统资源
- 由于共享内存地址空间(栈指针不共享),同一进程内的线程通信无须系统干预
- 不同进程的线程切换会引起进程切换
- 切换同进程的线程,开销很小
- 切换进程,开销很大
- 实现方式
- 用户级线程:从用户视角看的线程,有关线程管理的工作都由应用程序完成,无须内核干涉
- 内核级线程:从操作系统视角看的进程(内核级线程才是处理机分配的单位)
- 组合:用户级线程与内核级线程组合
- 多线程模型
- 多对一模型:
- 优点:进程管理开销小,效率高
- 缺点:并发度低:一个线程被阻塞,整个进程阻塞
- 一对一模型:
- 优点:各个线程分配到多核处理机并发执行,并发度高
- 缺点:开销大(需要到核心态
- 多对多模型:集合二者之长
- 多对一模型:
2.2处理机调度
2.2.1 调度概念
- 基本概念:按照某种算法选择一个
- 层次
- 高级调度(作业调度):从后备队列中选择合适的作业将其调入内存,并为其创建进程
- 中级调度(内存调度):从挂起队列中选择合适的进程将其数据调回内存
- 低级调度(进程调度):从就绪队列中选择一个进程为其分配处理机
- 联系与对比
- 高级调度
- 外存 → \rightarrow → 内存(面向作业)
- 频率最低
- 中级调度
- 外存 → \rightarrow → 内存(面向进程)
- 频率中等
- 低级调度
- 内存 → \rightarrow → CPU
- 频率最高
- 高级调度
- 补充
- 为了减轻系统分担,提高资源利用率,暂时不执行的进程会被调到外存从而变为挂起态
- 七状态模型:在五状态模型的基础上,加入了“就绪挂起”和“阻塞挂起”两种状态
2.2.2 调度目标
- C P U 利用率: C P U 有效工作时间 C P U 有效工作时间 + C P U 空闲等待时间 CPU 利用率:\cfrac{CPU 有效工作时间}{CPU 有效工作时间+CPU 空闲等待时间} CPU利用率:CPU有效工作时间+CPU空闲等待时间CPU有效工作时间
- 系统吞吐量:单位时间内CPU 完成作业的数量
- 周转时间
- 周转时间:作业完成时间-作业提交时间
- 平均周转时间: ∑ i = 1 n 作业 i 的周转时间 n \cfrac{\displaystyle\sum^n_{i=1}作业i的周转时间}{n} ni=1∑n作业i的周转时间
- 带权周转时间: 作业周转时间 作业实际运行时间 \cfrac{作业周转时间}{作业实际运行时间} 作业实际运行时间作业周转时间
- 等待时间:进程处于等处理机的时间之和
- 响应时间:从用户提交请求 到系统首次产生相应所用的时间
2.2.3调度的实现
- 调度器
- 排队器
- 分派器
- 上下文切换器
- 时机
- 能调度
- 主动放弃
- 进程正常终止
- 运行过程异常终止
- 主动阻塞(如等待I/O)
- 被动放弃
- 分给进程的时间片用完
- 有更紧急的事情要处理(如I/O中断)
- 有更高优先级的进程进入就绪队列
- 主动放弃
- 不能调度
- 在处理中断的过程中
- 进程在操作系统内核程序临界区中
- 原子操作(原语)
- 能调度
- 切换与过程
- 切换过程
- 对原来运行进程各种数据的保存
- 对新的进程各种数据的恢复
- 重要结论:进程调度、切换是有代价的,不是调度越频繁,并发度越高
- 切换过程
- 方式
- 非剥夺调度方式(非抢占式):只能由当前运行的进程主动放弃CPU
- 剥夺调度方式(抢占式):可由操作系统剥夺当前进程的CPU 使用权
- 闲逛进程:
- 没有就绪进程时,调度闲逛进程(idle)运行
- 闲逛进程不需要CPU 以外的资源,不会被阻塞
,
- 两种线程调度
- 用户级线程调度
- 内核级线程调度
2.2.4调度算法
高响应比优先
响应比 = 已等待时间 + 需要运行时间 需要运行时间 响应比=\cfrac{已等待时间+需要运行时间}{需要运行时间} 响应比=需要运行时间已等待时间+需要运行时间
多级反馈队列调度算法
- 多个队列,拥有多个优先级。第1队列最高,2次之,逐个降低
- 每个队列运行时间不同。优先级越高,时间片越小。
- 每个队列采用FCFS。新进程进入后放入第1队列末尾,在时间片内完成则撤离系统,未完成则转到下一个队列末尾。
对比
FCFS | SJF (SPF) | HHRN | RR | MFQ | |
---|---|---|---|---|---|
先来先服务 | 短作业优先 (短进程优先) | 高响应比优先 | 时间片轮转 | 多级反馈队列 | |
优点 | 公平 实现简单 | 平均等待时间少 效率高 | 兼顾长短作业 | 兼顾长短作业 | 兼顾长短作业 有较好响应时间 可行性强 |
缺点 | 不利于短作业 | 长作业容易饥饿 | 计算响应比的开销大 | 平均等待时间长 上下文切换浪费时间 | |
适用系统 | 无 | 作业调度 批处理系统 | 无 | 分时系统 | 相当实用 |
抢占与否 | 非抢占 | 抢占与非抢占 | 抢占与非抢占 | 抢占 | 不一定 |
默认 | 非抢占 | 非抢占 | 非抢占 | 抢占 | 抢占 |
2.1.1进程同步互斥的基本概念
- 进程同步
- 并发带来了异步性,有时候需要通过进程同步来解决异步问题
- 有的进程之间需要相互配合地完成工作,各进程的工作推进需要遵循一定的先后顺序
- 进程互斥
- 对临界资源的访问,需要互斥的进行
- 组成
- 进入区:检查是否可以进入临界区,可进入则“上锁”
- 临界区:访问临界资源的那段代码
- 退出区:负责“解锁”
- 剩余区:其余部分代码
- 原则
- 空闲让进:临界区空闲时,应运行一个进程访问
- 忙则等待:临界区正在被访问时,其他视图访问的进程需要等待
- 有限等待:要在有限的时间内进入临界区,保证不会饥饿
- 让权等待:进不了临界区的进程,要释放处理机,防止忙等待
2.3.2实现临界区互斥的基本方法
软件实现
允许turn进程进入
flag[]:进程是否进入临界区
Pi | Pj | 区域划分 | 说明 | 缺点 | |
---|---|---|---|---|---|
单标志法 | while(turn != 0); critical section; turn = 1; remainder section; | while (turn != 1); critical section; turn = 0; remainder section; | 进入区 临界区 退出区 剩余区 | i=0, j=1 进入区只检查,不上锁 退出区上锁自己,解锁对方 | 不遵循“空闲让进” |
双标志先检查法 | while (flag[j]); flag[i]=true; critical section; flag[i]=false; remainder section; | while (flag[i]); flag[j]=true; critical section; flag[j]=false; remainder section; | 进入区 进入区 临界区 退出区 剩余区 | 进入区检查后上锁 退出区解锁 | 不遵循“忙则等待” |
双标志后检查法 | while (flag[j]); flag[i]=true; critical section; flag[i]=false; remainder section; | while (flag[i]); flag[j]=true; critical section; flag[j]=false; remainder section; | 进入区 进入区 临界区 退出区 剩余区 | 进入区上锁后检查 退出区解锁 | 不遵循“空闲让进” 不遵循“有限等待” |
Peterson | flag[i]=true; turn=j; while (flag[j]&&turn==j); critical section; flag[i]=false; remainder section; | flag[j]=true; turn=i; while (flag[i]&&turn==i); critical section; flag[j]=false; remainder section; | 进入区 进入区 进入区 临界区 退出区 剩余区 | 进入区“争取-谦让” 进入区检查对方想进和谦让结果 | 不遵循“让权等待” |
硬件实现方法
- 中断屏蔽方法
- 使用“关/开中断”指令实现
- 优点:简单高效
- 缺点:只使用于单处理机;只适用于操作系统内核进程
- TestAndSet(TS/TSL)
- 过程
- old记录是否上锁
- lock设置为true
- 检查old是否上锁
- 上锁则重复上诉操作
- 优点:实现简单;适用于多出力系统
- 缺点:不满足“让权等待”
- 过程
- Swap指令(XCHG,Exhange):逻辑同TS
2.3.4信号量
- 整型信号量:缺点:不满足“让权等待”原则
- 记录型信号量:优点:
- 实现了系统资源的申请和释放
- 实现了进程互斥和同步
整型信号量
int S;
wait(S){
while (S <= 0);
S--;
}
signal(S){
S++;
}
记录型信号量
typedef struct{
int value;
struct process *L;
}semaphone;
//Process P
void wait(semaphone S){
if(--S.value<0){
P add to S.L;
block(S.L);
}
}
void signal(semaphone S){
if(++S.value<=0){
remove P from S.L;
wakeup(P);
}
}
整型信号量违背了让权等待原则。
记录型信号量可以阻塞和唤醒进程。
信号量机制
- 实现进程互斥
- 分析问题确定临界区
- 设置互斥信号量,初值为1
- 临界区之前对信号量进行P操作
- 临界区之后对信号量进行V操作
- 实现进程同步
- 分析问题,找出哪里需要实现“一前一后”的同步关系
- 设置同步信号量,初值为0
- 在“前操作”之后执行V操作
- 在“后操作”之前执行P操作
- 实现进程的前驱关系
- 分析问题,把每一对前驱关系看出一个同步问题
- 每一对前驱关系设置同步信号量,初值为0
- 在“前操作”之后执行V操作
- 在“后操作”之前执行P操作
2.3.5管程
- 引入缘由:解决信号量机制编程麻烦、易出错问题
- 组成(类)
- 共享数据结构
- 对数据结构初始化的语句
- 一组用来访问数据结构的过程(函数)
- 基本特征
- 各外部进程/线程只能通过管程提供的特定“入口”才能访问共享数据
- 每次仅允许一个进程在管程内执行某个内部过程
- 补充
- 各进程必须互斥访问管程的特性是由编译器实现的
- 可在管程中设置条件遍历及等待、唤醒操作以解决同步问题
2.3.6经典同步问题
实现互斥的P操作一定要在实现同步的P操作之后,即先P(S)再P(mutex),否则会导致死锁。
生产者-消费者问题
生产者消费者共享一块缓冲区,缓冲区不满生产者可以将消息放入缓冲区,否则必须等待;缓冲区不空消费者可以将消息从缓冲区取走,否则必须等待。缓冲区是临界资源,只允许生产者或消费者对其进行操作。
生产者和消费者对缓冲区是互斥关系,生产者和消费者又是同步关系,有生产物才可消费。
semaphore mutex = 1;//互斥信号量
semaphore full = 0;//缓冲区物品数量
semaphore empty = n; //缓冲区空闲区数量
producer(){
while(1){
生产
P(empty);//先检查缓冲区满没满
P(mutex);//顺序不能反,如果先互斥,再检查缓冲区满了发生堵塞,导致死锁
放入缓冲区
V(mutex);
V(full);
}
}
consumer(){
while(1){
P(full);//先检查缓冲区里有没有东西
P(mutex);
取走
V(mutex);
V(empty);
}
}
多生产者-消费者问题
多个生产者是互斥关系,配对的生产者和消费者是同步关系。
semaphore plate = 1;//盘子的互斥量
semaphore orange = 0;//盘中橘子个数
semaphore apple = 0;//盘中苹果个数
dad(){
while(1){
P(plate);
放苹果
V(apple);
}
}
mom(){
while(1){
P(plate);
放橘子
V(orange);
}
}
son(){
while(1){
P(orange);
拿走橘子
V(plate);
}
}
dau(){
while(1){
P(apple);
拿走苹果
V(plate);
}
}
读者-写者问题
- 允许多个读者读
- 只允许一个写者写
- 任一写者写操作完成之前不允许其他读者或写者工作
- 写者写之前已有的读者和写者全部退出
(3,4合一块就是写者写的过程中不允许别的打扰)
读进程优先
semaphore count = 0;//当前读者数量
semaphore mutex = 1;//互斥信号量
semaphore rw = 1;//保证一个写者和其他所有互斥
writer(){
while(1){
P(rw);
写
V(rw);
}
}
reader(){
while(1){
P(mutex);
if(count==0) P(rw);
count++;
V(mutex);
读
P(mutex);
count--;
if(count==0) V(rw);
V(mutex);
}
}
写进程优先/读写公平法
semaphore count = 0;//当前读者数量
semaphore mutex = 1;//互斥信号量
semaphore rw = 1;//保证一个写者和其他所有互斥
semaphore w = 1;//实现写进程优先
writer(){
while(1){
P(w);//***
P(rw);
写
V(rw);
V(w);//***
}
}
reader(){
while(1){
P(w);//***
P(mutex);
if(count==0) P(rw);
count++;
V(mutex);
V(w);//***
读
P(mutex);
count--;
if(count==0) V(rw);
V(mutex);
}
}
哲学家进程问题
- 两两相邻哲学家对中间的一支筷子是互斥
- 没有同步关系
要解决的是,如果避饥饿和死锁
方法有三:最多4名哲学家同时进餐;只有当左右筷子都可用才允许哲学家拿起筷子;技术好哲学家先拿左边筷子,偶数好哲学家相反
方法二代码
semaphore chop[5]={1,1,1,1,1);
semaphore mutex = 1;
Pi(){
do{
P(mutex);
P(chop[i%5]);
P(chop[(i+1)%5]);
V(mutex);
吃饭
V(chop[i%5]);
V(chop[(i+1)%5]);
思考
}while(1);
}
吸烟者问题
三个抽烟者分别拥有烟草,纸,胶水,供应者无限每次提供其中两种在桌上。其中一个吸烟者拿起桌上的两种恰好满足三种不同的东西就卷起抽掉。
供应者和抽烟者是同步关系
三个抽烟者是互斥关系(不能同时满足抽烟条件)
int num = 0;
semaphore offer1 = 0;//第一种供应物
semaphore offer2 = 0;//第二种供应物
semaphore offer3 = 0;//第三种供应物
semaphore finish = 0;//抽烟是否完成
process provider(){
while(1){
num++;
num %= 3;
if(num==0) V(offer1);
else if(num==1) V(offer2);
else V(offer3);
把东西放桌上
P(finish);
}
}
porcess smoker1(){
while(1){
P(offer1);
抽烟
V(finish);
}
}
porcess smoker2(){
while(1){
P(offer2);
抽烟
V(finish);
}
}
porcess smoker3(){
while(1){
P(offer3);
抽烟
V(finish);
}
}
2.4死锁
2.4.1死锁概念
- 定义:各进程互相等待对方手里资源,导致各进程都阻塞,无法推进
- 区别
- 死锁:至少两个进程一起死锁,死锁处于阻塞态
- 饥饿:可以只有一个进程饥饿,饥饿进程可能阻塞也可能就绪
- 死循环:可能只有一个进程发生死循环,死循环的进程可上处理机
- 死锁和饥饿是操作系统的问题,死循环是应用程序员的问题
- 必要条件
- 互斥条件:对必须互斥使用的资源的争抢才会导致死锁
- 不剥夺条件:进程保持的资源只能主动释放,不可强行剥夺
- 请求和保持条件:保持着某些资源不放的同时,请求别的资源
- 循环等待条件
- 存在一种进程资源的循环等待链
- 循环等待未必死锁,死锁一定有循环等待
- 发生时机:对不可剥夺资源的不合理分配,可能导致死锁
- 处理策略
- 预防死锁:破坏产生死锁的四个必要条件
- 避免死锁:避免系统进入不安全状态(银行家算法)
- 死锁的检测和解除:允许死锁发生,系统负责检测出死锁并解除
2.4.2 死锁预防
- 破坏互斥条件
- 将临界资源改造为可以共享使用的资源
- 缺点:可行性不高,很多时候无法破坏互斥条件
- 破坏不剥夺条件
- 法①:申请得不到满足时,立即释放所有资源
- 法②:申请的资源被其他进程占用时,由操作系统协助剥夺(考虑优先级
- 缺点:
- 实现复杂
- 剥夺资源可能导致部分工作失效
- 反复申请和释放资源导致系统开销大
- 可能导致饥饿
- 破坏请求和保持条件
- 运行前分配好所有所需的资源,之后保持
- 缺点
- 资源利用率低
- 可能导致饥饿
- 破坏循环等待条件
- 给资源编号,必须按照编号从小到达的顺序申请资源
- 缺点
- 不方便增加新设备
- 会导致资源浪费
- 用户编程麻烦
2.4.3 死锁避免
- 安全序列:按照某种进程推进顺序为每个进程分配资源,使得所有进程皆可完成
- 安全状态:若至少存在一个安全序列,则系统处于安全状态
- 银行家
- 问题描述
- 每个进程有MAX(该进程所需最大资源)
- 每个进程有Allocation(该进程已分配资源)
- 系统有Available(当前系统剩余资源)
- 需要完成所有进程
- 安全性算法
- 每个进程Need=MAX-Allocation(该进程还需要的资源)
- Ini:Work=Available,queue<>q
- while(存在i使得Need[i]<=Work)q.push(i);Work+=Allocation[i]
- 如果q包含所有进程,则处于安全状态;反之不处于
- 问题描述
2.4.4 死锁检测和解除
- 检测
- 资源分配图
- 两种结点
- 进程结点
- 资源结点
- 两种边
- 进程结点->资源结点(请求边)
- 资源结点->进程结点(分配边)
- 两种结点
- 死锁检测算法
- 不阻塞进程:其申请的资源数足够的进程
- 死锁定理:若资源分配图是不可完全简化的,说明发生了死锁
- 依次消除与不阻塞进程相连的边,直到无边可消
- 资源分配图
- 解除
- 资源剥夺法
- 撤销进程法(终止进程法)
- 进程回退法
第三章 内存管理
3.1内存管理概念
3.1.1 内存管理的基本原理和要求
- 功能
- 内存和分配和回收:操作系统完成主存空间的管理和分配
- 地址转换:逻辑地址和物理地址直接的转换
- 内存共享:运行多个进程访问内存的同一部分
- 存储保护:保证各道作业在各自的存储空间内运行,互不干扰
- 原理
- 程序到进程
- 编译:源代码编译成若干目标模块
- 链接
- 链接目标模块和所需库函数,形成拥有逻辑地址的装入模块
- 方式
- 静态链接:装入前链接成完整装入模块
- 装入时动态链接:运行前边装入边链接
- 运行时动态链接:运行时需要目标模块才链接再装入
- 装入:
- 将装入模块装入内存运行
- 方式
- 绝对装入:编译时产生绝对地址
- 可重定位装入:装入时逻辑地址转为物理地址
- 动态运行时装入:运行时将逻辑地址转为物理地址
- 逻辑地址和物理地址:相对地址和绝对地址
- 进程内存映像
- 代码段:程序的二进制代码,只读、共享
- 数据段:运行时加工处理对象,包含全局变量和静态变量
- PCB:存放再系统区。系统由此控制和管理进程
- 堆:存放动态分配的变量
- 栈:实现函数调用
- 内存保护
- 上下限寄存器:CPU 访问时,判断有无越界
- 重定位寄存器和界地址寄存器
- 基地址寄存器和限长寄存器
- 存放最小物理地址的最大逻辑地址
- 内存共享
- 纯代码:可重入代码
- 可同时访问,只读
- 内存分配与回收
- 为适应不同大小程序:固定分区分配到动态分区分配
- 为提供内存利用率:连续分配方式到离散分配方式(页式存储管理)
- 引入分段存储管理目的:满足用户在编程和使用方面的要求
- 程序到进程
*3.1.2 覆盖与交换
- 覆盖技术
- 一个固定区
- 存放最活跃的程序段
- 固定区的程序段在运行时不会调入调出
- 若干覆盖区
- 不可能同时被访问程序段可共享一个覆盖区
- 覆盖区的程序段在运行时会根据需要调入调出
- 必须由程序员声明覆盖结构,操作系统完成自动覆盖
- 缺点:对用户不透明,增加用户的编程负担
- 一个固定区
- 交换技术
- 内存紧张时,换出某些进程以腾出内存,再换入某些进程
- 磁盘分成文件区和对换区,换出的进程放在对换区
- 两者区别
- 覆盖是再同一个进程或程序中的
- 交换是在不太进程(作业)之间的
3.1.3 连续分配管理方式
- 单一连续分配
- 内存分为系统区和用户区,用户程序再用户区
- 只支持单道程序,无外部碎片,有内部碎片
- 固定分区分配
- 内存用户空间划分为若干固定大小分区,每个分区一道作业
- 支持多道程序,无外部碎片,有内部碎片
- 方式
- 分区大小相等
- 分区大小不等
- 动态分区分配
- 在进程装入内存时,根据进程大小动态调整地建立分区
- 支持多道程序,无内部碎片,有外部碎片
- 外部碎片可用“紧凑”技术解决
- 分配策略
- 首次适应:空闲分区地址递增,从头开始顺序查找
- 临近适应:上次查找结束的位置开始查找
- 最佳适应:最小空闲分区
- 最坏适应:最大空闲分区
- 回收情况
- 回收区之后有相邻的空闲分区
- 回收区之前有相邻的空闲分区
- 回收区前、后都有相邻的空闲分区
- 回收区前、后都没有相邻的空闲分区
3.1.4 基本分页存储管理
基本概念
- 思想:把进程分页,各个页面离散地放到各个的内存块中
- 重要概念
- “页框、页帧、内存块、物理块”,“页、页面”
- “页框号、页帧号、内存块号、物理块号”,“页号、页面号”
- 实现地址转换
- ①计算出逻辑地址对应的页号
- ②找出对应页面在内存中的存放位置
- ③算出逻辑地址对应的页内偏移量
- ④物理地址=页面地址+页内偏移量
- 逻辑地址结构
- 作用于进程
- 页号=逻辑地址/页面大小
- 页偏移量=逻辑地址%页面大小
- 页表
- 作用于内存
- 页表记录进程页面和实际存放内存块之间的对应关系
- 一个进程对应一张页表,进程每一页对应一个页表项
- 页表项由页号(隐含)、块号组成
- 每个页表项的长度是相同的
进程的块称之为页或者页面
内存的块称为页框或者页帧
外存的块称为块或者盘块
页表由页表项组成
页表项由页号和块号组成
基本地址变换结构
- 页表寄存器的作用
- 存放页表起始地址
- 存放页表长度
- 地址变换过程
- ①根据逻辑地址算出页号和页偏移量
- ②检查页号的合法性
- ③根据页表起始地址、页号\textbf{找到对应表项}
- ④根据页表项内存块号和页偏移量算得物理地址
- ⑤访问\textbf{物理内存}对应的存储单元
- 其他细节
- 页内偏移量位数和页面大小之间的关系
- 页式管理中地址是一维的
- 实际应用中,使n*页表项=页框
- 为了方便查找,页表项一般是在连续的内存块中
具有快表的地址变换结构
- 基本地址变换结构
- ①先访问内存块号
- ②再访问物理地址
- 具有快表的地址变换结构
- 查快表
- 命中
- 未命中
- ①同上,两次访存
- ②结果插入快表
- 查快表
两级页表
- 单页表缺陷
- 所有页表连续存放,需要很大的连续空间
- 在一段时间内并非所有页面用得到,没必要页表常驻内存
- 结构
- 将长长的页表再分页
- 逻辑地址结构:一级页号,二级页号,页内偏移量
- 术语:页目录表,外层页表,顶级页表
- 变换地址
- ①按地址结构将逻辑地址拆分成三部分
- ②从PCB读出目录表始地址,根据一级页号查页目录表
- ,找到下一级页表在内存中的存放位置
- ③根据二级页号查表,找到最终想访问的内存块号
- ④结合页内偏移量得到物理地址
- 细节
- 各级页表大小不能超过一个页面
- N级页表访问逻辑地址需要N+1次访存
3.1.5基本分段存储管理
- 分段
- 将地址空间按照程序自身逻辑关系划分为若干段,每段从0开始
- 每个段在内存中占据连续空间,各段可以不相邻
- 逻辑地址结构:段号、段内地址
- 段表
- 记录逻辑段到实际存储地址的映射关系
- 每个段对应一个段表项,段表项长度相同
- 段表项由段号(隐含)、段长,基地址组成
- 地址变换
- ①由逻辑地址得到段号、段内地址
- ②检查越界:段号与段表寄存器长度比较
- ③由段表始址、段号找到对应段表项
- ④检查越界:根据段表记录的段长
- ⑤由段表中“基址+段内地址”得到物理地址
- ⑥访问目标单元
- 分段与分页
- 分页对用户不可见,分段对用户可见
- 分页的地址空间是一位的,分段的地址空间是二维的
- 分段更容易实现信息的保护和共享
- 分页和分段都是两次访存,都可引入快表
3.1.6段页式管理
- 分段+分页
- 按自身逻辑分段,每段分为大小相等的页面
- 内存分为内存块,以块为单位为进程分配内存
- 逻辑地址:段号,页号,页偏移量
- 段表、页表
- 段表项由段号(隐含)、段长,基地址组成
- 页表项由页号(隐含)、块号组成
- 地址变换
- ①由逻辑地址得到段号、页号、页偏移量
- ②检查越界:段号与段寄存器中的段长度相比
- ③由段表始址、段号找到对应表项
- ④检查越界:页号与段表记录的页表长度相比
- ⑤由段表的页表地址、页号得到查询页表,找到相应的页表项
- ⑥物理地址=页面地址+页内偏移量(页面存放)
- ⑦访问目标单元
- 访存
- ①查段表②查页表③访问物理地址
- 引入快表:以段号和页号为关键字
3.2虚拟内存管理
3.2.1 虚拟内存的基本概念
- 传统存储特征缺点
- 一次性:作业数据必须一次性全部调入内存
- 驻留性:作业数据在整个运行过程常驻内存
- 局部性原理
- 时间局部:现在访问的指令和数据,在不久后可能会再次被访问
- 空间局部:现在访问的内存单元周围空间,不久后可能会被访问
- 高速缓存技术:使用频繁的数据放到更高速的存储器中
- 虚拟内存定义和特征
- 程序无须全部装入,运行时动态调入数据,内存不够则换出一些数据
- 特征
- 多次性:无须一次全部装入内存,允许分成多次调入
- 对换性:无须常驻内存,允许运行中换入换出
- 虚拟性:逻辑上扩充了内存容量
- 实现
- 请求调页功能:访问的信息不在内存时,操作系统从外存调入
- 页面置换功能:内存不够时,暂时不用的信息调出
- 实现
- 请求分页存储管理
- 请求分段存储管理
- 请求段页式存储管理
3.2.2 请求分页管理方式
- 页表机制
- 页号,物理块号
- 状态位P:表示页面是否已经在内存中
- 访问字段A:供置换算法选择换出页面时参考
- 修改位M:表示页面调入内存是否修改过,修改过需要写回外存
- 外存地址:页面在外存存放的地址
- 缺页中断机构
- ①找到页表项后检查是否在内存,无则缺页中断
- ②缺页中断处理,将目标页面调入,可能调出页面
- 缺页中断属于内中断,属于故障,即可能被系统修复
- 一条指令执行过程中可能产生多次缺页中断
- 地址变换
- ①找到页表项是需要检查页面是否在内存中
- ②若页面不在内存中,需要请求调页
- ③内存不够时,需要换出页面
- ④页面调入内存后,需要修改相应页表项
3.2.3 页框分配
- 驻留集:请求分页存储管理中给进程分配内存块大小的集合
- 页面分配与置换
- 固定分配VS可变分配:进程运行期间驻留集大小是否可变
- 局部置换VS全局变置换:发生缺页时是否只能换出自己的页
- 固定分配局部置换:
- 可变分配全局置换:
- 可变分配局部置换:
- 调入时机
- 预调页策略:进程运行前
- 请求调页策略:运行时发生缺页
- 调入位置
- 对换区:连续存储,速度快;文件区:离散存储,速度慢
- 对换区足够大:运行前复制到对换区,调入调出都是在内存和对换区之间
- 对换区不够大:不会修改的数据从文件区调入;会修改的数据调出对换区,需要再调入
- UNIX:第一次使用的页面都是从文件区调入;调出的页面写回对换区
- 调入过程
- 存在位为0时,发出缺页中断,响应后转入缺页中断处理程序
- 查找页表得到该页物理块号
- 判断是否满了
- 内存未满,所缺页调入内存
- 内存已满,选出一页换出
- 该页修改位为0,无须写回磁盘
- 该页修改位为1,写回磁盘
- 调入所缺页
- 修改页表相应表项,存在位置为1
- 访存
3.2.4页面置换算法
中文名 | 英文名 | 规则 | 优缺点 |
---|---|---|---|
最佳置换算法OPT | Optimal | 优先淘汰最长时间内不会被访问的页面 | 缺页率最小,性能最好,实现Impossible |
先进先出置换算法FIDO | First In First Out | 优先淘汰最先进入内存的页面 | 实现简单,性能差,可能出现Belady异常 |
最近最久未使用置换算法LRU | Least Recently Used | 优先淘汰最近最久没访问的页面 | 性能很好,但需要硬件支持,算法开销大 |
时钟置换算法 CLOCK(NRU | Not Recently Used | (访问位)。有则改1,无则替换。替换:从上次替换的下一个位置开始,遇1改0,遇0替换。 | 实现简单,算法开销小,但未考虑页面是否被修改 |
改进型CLOCK | Not Recently Used | 用(访问位,修改位)形式描述 | 算法开销较小,性能也不错 |
3.2.5 抖动和工作集
- 抖动
- 定义:页面频繁换入换出(刚换出又要换入
- 原因:分配给进程的物理块不够
- 工作集
- 定义:某段时间间隔里,进程实际访问页面的集合
- 要求:一般驻留集大小不能小于工作集大小
3.2.6内存映射文件
3.2.7虚拟存储器性能影响因素
3.2.8地址翻译
第四章 文件管理
4.1文件系统基础
4.1.1 文件的基本概念
- 初识文件管理
- 文件定义:一组有意义的信息的集合
- 文件属性:文件名、标识符、类型、位置、大小、保护信息 … \dots …
- 文件的逻辑结构:文件内部如何组织
- 目录结构:文件之间如何组织
- 操作系统应提供的功能
- 系统调用
- create
- delete
- open
- read
- write
- 文件物理结构:文件应如何存放在外存
- 存储空间的管理:如何管理外存的空闲块
- 其他文件管理功能
- 文件保护
- 文件共享
- 数据
- 数据项
- 基本数据项:数据中的最小逻辑单位,描述某种属性的一个值
- 组合数据项:多个基本数据项组成
- 记录:一组相关数据项的集合,描述某方面的属性
- 文件
- 一组相关元素的集合
- 有结构文件:由若干的相似的记录组成
- 无结构文件:字符流
4.1.2文件控制块和索引结点
- 文件属性
- 名称
- 类型
- 创建者
- 所有者
- 位置:指向设备和设备上文件的指针
- 大小
- 保护
- 创建时间、最后一次修改和存取时间
- 文件控制块FCB
- 一个FCB就是一个文件目录项。FCB的有序集合称为文件目录
- 基本信息
- 文件名
- 文件的物理位置
- 文件的逻辑结构
- 文件的物理结构
- 存取控制信息
- 文件主的存取权限
- 标准用户的存取权限
- 一般用户的存取权限
- 使用信息:
- 建立时间
- 上次修改时间
- … \dots …
- 索引结点
- UNIX采用文件名和描述信息分开,节省盘块
- 磁盘索引结点
- 指的是存放在磁盘上的索引结点。
- 每个文件有一个唯一的磁盘索引结点
- 文件主标识符:拥有该文件的个人或小组的标识符
- 文件类型:普通文件,目录文件,特别文件
- 文件存取权限:每类用户对该文件的存取权限
- 文件物理地址:每个索引结点含有13个地址项,以直接间接的方式给出所在盘块编号
- 文件长度:以字节为单位的文件长度
- 文件链接计数:在文件系统中所有指向该文件的文件名的指针计数
- 文件存取时间:文件最近存取时间、最近被修改时间、索引结点最近被修改时间
- 内存索引结点
- 文件被打开时,磁盘索引结点复制到内存中产生的结点,增加内容如下
- 索引结点编号:用于表示内存索引结点
- 状态:指示i结点是否被上锁或者修改
- 访问计数:进程访问则++,结束则–
- 逻辑设备号:文件所属文件系统的逻辑设备号
- 链接指针:分别指向空闲链表和散列队列的指针
Linux下,i节点其实就是可以这么认为,把i节点看作是一个指向磁盘上该文件存储区的地址。只不过这个地址我们一般是没办法直接使用的,而是通过文件名来间接使用的。事实上,i节点不仅包含了文件数据存储区的地址,还包含了很多信息,比如数据大小,等等文件信息。但是i节点是不保存文件名的。文件名是保存在一个目录项中。每一个目录项中都包含了文件名和i节点。
4.1.3文件的操作
- 创建文件
- 分配外存空间
- 创建目录项
- 删除文件
- 回收内存空间
- 删除目录项
- 打开文件
- 将目录项中的信息复制到内存的打开文件表中,并将打开文件表的索引号返回给用户
- 打开之后,对文件的操作不再需要每次都查询目录,可以根据内存中的打开文件表进行操作
- 每个进程都有字节的打开文件表,系统中也有一张总的打开文件表
- 进程打开文件表中特有的属性:读写指针、访问权限(只读?读写?)
- 系统打开文件表中特有的属性:打开计数器(有多少个进程打开该文件)
- 关闭文件
- 将进程打开表中的相应表项删除
- 系统打开文件表的打开计数器–。为0则删除系统表的表项
- 读文件:根据读指针、读入数据量、内存位置将文件数据从外存读入内存
- 写文件:根据写指针、写出数据量、内存位置将文件数据从内存写出外存
4.1.4 文件保护
- 访问类型
- 读、写、执行、添加、删除、列表清单
- 重命名、复制、编辑
- 这些高层功能通过系统程序调用低层系统实现
- 保护可以只在低层提供
- 访问控制
- 用一个ACL记录各个(组)用户对文件的访问权限
- 优点:实现灵活,可以实现复杂的文件保护功能
- 另外两种控制
- 口令
- 为文件设置一个口令,用户访问时需要提供口令,系统验证正确性
- 实现开销小,但口令一般存放再FCB或者索引结点中,不安全
- 加密
- 用密码对文件加密,用户访问时,需要密钥
- 安全性高,但是解密加密需要一定时间
- 口令
4.1.5 文件的逻辑结构
- 无结构文件
- 流式文件,以Byte为单位
- 优点管理简单,适用于基本信息单位不多的文件
- 缺点:大多数应用不适用
- 有结构文件
- 顺序文件
- 串结构:记录顺序与关键字无关
- 顺序结构:记录按关键字顺序排列
- 可变长记录的顺序文件按无法实现那随机存取,定长则可
- 定长记录、顺序结构的顺序文件可以快速减少
- 不方便增删
- 索引文件
- 建立一张索引表,每个记录对应一个表项,各记录不用顺序,方便增删
- 索引表本身就是定长记录的顺序文件,因此索引文件可以随机存取
- 若索引表按关键字顺序排序,则可支持快速检索
- 解决增删问题,实现了随机存取,索引表可能占用很大空间
- 索引顺序文件
- 将记录分组,每组对应一个索引表项
- 检索记录时先顺序检索索引表,找到分组,再顺序查找分组
- 当记录过多时,可记录多级索引表
- 哈希文件
- 键值直接决定物理地址
- 会引起冲突
- 顺序文件
4.1.6 文件的物理结构
方式 | 目录项内容 | 优点 | 缺点 | ||
---|---|---|---|---|---|
连续分配 | 为文件分配的块,必须是连续的磁盘块 | 起始块号、文件长度 | 顺序存取速度快、支持随机访问 | 会产生碎片,不利于文件扩展 | |
链接分配 | 隐式链接 | 除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针 | 起始盘块、结束盘块 | 可解决碎片问题,外存利用率高,文件扩展方便 | 只能顺序访问,不能随机访问 |
显示链接 | 建立一种文件分配表(FAT),显示记录判断的先后关系 (开机后FAT常驻内存) | 起始块号 | 可解决碎片问题,外存利用率高,文件扩展方便,通过FAT随机访问 | FAT需要占用一定的存储空间 | |
索引分配 | 为文件数据块建立索引表。若文件太大,可采用链接方案、多层索引、混合索引 | 链接方案记录的是第一个索引块的块号,多层或混合索引记录的是顶级索引块的块号 | 支持随机访问,易于实现文件的扩展 | 索引表需占用一定存储空间。访问数据块前需要先读入索引块。若采用链接方案,查找索引块可能需要很多次读磁盘操作 | |
混合索引分配 | 多种索引分配方式的结合 | 在文件的顶级索引表中,包含了直接地址、一级间接索引、二级间接索引 | 对于小文件来说,访问一个数据块所需的读磁盘次数更少 |
4.2.1 目录的基本概念
FCB的有序集合称为文件目录,一个FCB是一个文件目录项。
4.2.2目录结构
- 单级目录结构:一个系统只有一章目录表,不允许文件重名
- 两级目录结构
- 分成主文件目录MFD和用户文件目录UFD
- 不同用户文件可以重名,但不能对文件分类
- 多级目录结构
- 也称树形目录结构
- 不同目录下的文件可以重名,可以对文件进行分类,不方便共享
- 系统根据“文件路径”找到目标文件
- 从根目录出发的路径是绝对路径
- 从当前目录出发的路径是相对路径
- 无环图目录结构
- 在树形目录结构基础上,增加一些指向同一结点的有向边
- 为共享结点设置共享计数器,计数器为0才真正删除该结点
目录的索引结点 - 除文件名之外的所有信息都放到索引结点,每个文件对于一个索引结点
- 目录项只包含文件名、索引结点指针,因此每个目录项的长度大幅度减少
- 因此每个磁盘块可以存放更多目录项,检索文件时磁盘的I/O次数减少
4.2.3目录的操作
- 搜索:找到文件的对应目录项
- 创建文件:在目录中增加一个目录项
- 删除文件:在目录中删除对应的目录项
- 创建目录:用户创建自己的用户文件目录,再创建子目录
- 删除目录
- ①不删除非空目录,删除时要先删除目录中的所有文件,并递归删除子目录
- ②可删除非空目录,目录中的文件夹和子目录同时被删除
- 移动目录:文件的路径名随之改变
- 显示目录:可请求显示目录内容,如显示所有文件及属性
- 修改目录:某些文件属性保存在目录中,因而这些属性的变换需要改变相应的目录项
*4.2.4目录实现
- 线性列表
- 采用文件名和数据块指针
- 创建:先搜索目录确定没有同名文件,然后目录中增加一个新的目录项
- 删除
- 根据文件名搜索目录,释放空间
- 重用目录项
- 可以将目录项标记为不再使用
- 将其加到空闲目录项的列表
- 将目录的最后一个目录项复制到空闲位置
- 优点:实现简单,链表结构删除简单
- 缺点:查找费时
- 哈希表
- 根据文件名得到一个值,并返回指向线性表中元素的指针
- 优点:查找非常迅速,插入和删除简单
- 缺点:避免冲突
4.2.5 文件共享
- 硬链接
- 基于索引结点的共享方式
- 各个用户的目录项指向同一个索引结点
- 索引结点需要有链接计数count
- 删除文件时,只删除目录项,且count–
- 只有count==0时,才真正删除结点
- 软链接
- 利用符号链实现文件共享
- 在一个Link型的文件中记录共享文件的存放路径
- 系统根据路径一层层查找目录,最终找到共享文件
- 即使软链接指向的共享文件已被删除,Link依旧存在,只是找不到对应目录项
- 由于软链接的方式访问共享文件时需要查询多级目录,会有多次I/O操作,因此用软链接访问
4.3 文件系统
4.3.1 文件系统结构
- I/O控制
- 包括设备驱动程序和中断处理程序
- 在内存和磁盘之间传输信息
- 设备驱动翻译出指令,硬件控制利用指令使I/O设备与系统交互
- 基础文件系统
- 向对应设备驱动程序发出指令,以读取和写入磁盘的物理块
- 也管理内存缓冲区,并保存各种文件系统、目录和数据块的缓存
- 文件组织模块
- 由逻辑块和物理块组成
- 可以将逻辑块地址转成物理块地址
- 还包括空闲空间管理器,以跟踪未分配的块
- 逻辑文件系统
- 管理元数据信息
- 元数据包括文件系统的所有结构,而不包括实际数据
- 管理目录结构,根据文件名为文件组织模块提供信息
- 通过文件控制块维护文件结构
- 还负责文件保护
4.3.2 文件系统布局
磁盘中的文件系统
磁盘 { M B R 分区表 磁盘分区 磁盘分区 磁盘分区 { 引导块 超级块 空闲空间管理 i 结点 根目录 文件和目录 磁盘分区 磁盘分区 磁盘\left\{\begin{aligned} &MBR\\ &分区表\\ &磁盘分区\\ &磁盘分区\\ &磁盘分区\left\{\begin{aligned} &引导块\\ &超级块\\ &空闲空间管理\\ &i结点\\ &根目录\\ &文件和目录\\ \end{aligned}\right.\\ &磁盘分区\\ &磁盘分区\\ \end{aligned}\right. 磁盘⎩ ⎨ ⎧MBR分区表磁盘分区磁盘分区磁盘分区⎩ ⎨ ⎧引导块超级块空闲空间管理i结点根目录文件和目录磁盘分区磁盘分区
- 多数磁盘划分为一个或多个分区,每个分区有一个独立的文件系统
- 文件系统包含信息: … \dots …总的块数,空闲块数量和位置,目录结构,各个具体文件
- 主引导记录MBR
- 位于0号扇区,用以引导计算机
- MBR后面是分区表
- BIOS读入并执行MBR,MBR确定活动分区,读入引导块
- 引导块
- 引导块的程序负责启动该分区的操作系统
- Windows操作系统称之为分区引导扇区
- 超级块
- 包含文件系统的所有关键信息
- 计算机启动或者文件系统首次使用,超级块会被载入内存
- 典型信息
- 分区的块的数量,块的大小
- 空闲块的数量和指针
- FCB数量和指针
- 空闲块信息:待续
- 一组i结点:每个文件对应一个i结点,i结点说明文件的方方面面
- 根目录:存放文件系统目录树的根部
- 其他:其他所有目录和文件
内存中的文件系统
- 结构
- 内存中的安装表:包含每个已安装文件系统分区的有关信息
- 内存中的目录结构的缓存包含最近访问目录的信息。对安装分区的目录,它可以包含一个指向分区表的指针
- 整个系统的打开文件表:包含每个打开文件的FCB副本及其他信息
- 每个进程的打开文件表:包含整个系统的打开文件表中适当条目的指针, … \dots …
- 创建文件
- 应用程序调用逻辑文件系统
- 逻辑文件系统知道目录结构格式,将文件分配一个新的FCB
- 系统将相应的目录读入内存,使用新的文件名和FCB进行更新,之后写回磁盘
- 使用文件
- 打开文件,系统调用open()将文件名传给逻辑文件系统
- 搜索整个系统的打开文件表,确定该文件是否被打开
-
- 已被打开:在单个进程的打开文件表创建一个条目,让其指向现有整个系统的打开文件表的相应条目
- 未被打开
- 根据给定文件名来搜索目录结构
- 找到文件后,FCB复制到整个系统的打开文件表
- 该表不仅存储FCB,而且跟踪打开文件的进程的数量
- 在单个进程的打开文件表创建一个条目,通过指针将整个系统打开文件表的条目与其他域相连
- open()返回的是一个指向单个进程的打开文件表中的适当条目的指针
- 之后所有的文件操作都通过指针执行
- 一旦打开,访问文件都通过文件描述符(Windows称之为文件句柄)
4.3.3 外存空闲空间管理
文件系统分区称为卷
卷可以是磁盘的一部分,卷也可以是整个磁盘,卷还可以是由多个磁盘组成
盘块由若干盘区组成
卷
a
{
目录区
文件区
卷
b
{
目录区
文件区
}
物理盘
1
\left.\begin{aligned} &卷a\left\{\begin{aligned} &目录区\\\hline &文件区\\\hline \end{aligned}\right.\\ &卷b\left\{\begin{aligned} &目录区\\\hline &文件区\\\hline \end{aligned}\right.\\ \end{aligned}\right\}物理盘1
卷a{目录区文件区卷b{目录区文件区⎭
⎬
⎫物理盘1 $ \hspace{2cm}$
卷
c
{
目录区
文件区
}
物理盘
2
⋮
}
物理盘
3
卷c\left\{\begin{aligned} &\left.\begin{aligned} &目录区\\\hline &文件区\\ \end{aligned}\right\}物理盘2 \\ &\left.\begin{aligned} &\hspace{1cm}\\ & \vdots\\\hline \end{aligned}\right\}物理盘3\\ \end{aligned}\right.
卷c⎩
⎨
⎧目录区文件区}物理盘2⋮⎭
⎬
⎫物理盘3
- 空闲表法
- 定义:属于连续分配方式,为每个文件分配一块连续的存储空间
- 空闲盘块表:序号,第一个空闲盘块号,空闲盘块数
- 分配:采用艘次适应算法和最佳适应算法
- 回收:同内存动态分区分配回收,需考虑前后区相邻接情况
- 空闲链表法
- 将空闲盘区拉成一条链
- 空闲盘块链
- 以盘块为单位拉成一条链
- 分配:从链首开始,依次摘下适当数目的空闲盘块
- 回收:回收的盘块依次插入链尾
- 优点:分配和回收简单
- 缺点
- 为一个文件分配空间时可能要重复多次,效率低
- 以盘块为单位,链会很长
- 空闲盘区链
- 以盘区为单位拉成一条链
- 分配:通常采用最佳适应算法
- 回收:同内存动态分区分配回收,需考虑前后区相邻接情况
- 优点
- 分配效率高
- 以盘区为单位,链短
- 缺点:分配和回收复杂
- 位示图法
- 利用二进制的一位来表示磁盘中一个盘块的使用情况
- 0:空闲,1:已使用
- 用m*n的二维位示图就可以表示m*n个盘块使用情况
- 王道书默认point、i和j从1开始
- 分配: p o i n t = n ( i − 1 ) + j point=n(i-1)+j point=n(i−1)+j
- 回收: i = ⌊ p o i n t − 1 n ⌋ + 1 , j = ( p o i n t − 1 ) % n + 1 i=\lfloor \cfrac{point-1}{n} \rfloor +1,j=(point-1)\%n+1 i=⌊npoint−1⌋+1,j=(point−1)%n+1
- 成组链接法
- 定义:结合了空闲表法和空闲链表法
- 思想
- 成组链块有n个指针
- 成组链块的前n-1指针指向空闲盘块号
- 成组链块的最后一个指针指向下一个成组链块
- 系统只需保存指向第一个成组链块的指针
- 分配
- 根据第一个成组链块的指针,分配,指针下移
- 如果指向成组链块,将该块读入内存,指针指向第一条记录,继续上诉操作
- 回收
- 成组链块的指针上移,再记录回收盘块号
- 成组链块链接数达到n时,将这些空闲盘块作为新的成组链块
- 优点:UNIX就是采用了这种方法,集合二者之长
空闲表法和空闲链表法不适用于大型文件系统,因为这会使空闲表或空闲链表太大。
表示空闲空间的位向量或第一个成组链块,以及卷中的目录区、文件划分信息都要存放再磁盘中,一般放在卷头的位置,在UNIX中称为超级块。在对卷中的文件操作之前,超级块需要预先读入系统空闲的主存,并且经常保持主存超级块与卷中超级块的一致性
4.3.4 虚拟文件系统
- 定义
- 虚拟文件系统VFS为用户程序提供了文件系统的统一操作
- 屏蔽了不同文件系统的差异和操作细节
- 实现
- VFS采用面向对象思想
- 抽象出一个通用的文件系统模型,定义了通用文件系统都支持的接口
- 新的文件系统只要支持并实现这些接口就可以安装和使用
- 对象类型
- 超级块对象:表示一个已安装(或称挂载)的特定文件系统
- 索引结点对象:表示一个特定的文件
- 目录项对象:表示一个特定的目录项
- 文件对象:表示一个与进程相关的已打开文件
- 对象类型
- 超级块对象
- 对应于文件系统超级块,用于存储已安装文件系统的元信息
- 元信息包含文件系统的基本属性
- (如文件系统类型,文件系统基本块大小,操作方法指针 … \dots …)
- 操作方法指针指向该超级块的操作方法表
- 主要是(分配inode,销毁inode,读inode,写inode,文件同步
- 索引结点对象
- 文件系统处理文件所需要的所有信息,都存放在索引结点的数据结构中,索引结点对文件唯一
- 只有当文件被访问时,才在内存中创建索引结点对象,会复制磁盘索引结点部分信息
- 有一个状态字:脏,说明对应磁盘索引结点必须被更新
- 提供的操作接口:创建新索引结点、创建硬链接、创建新目录 … \dots …
- 目录项对象
- 待续
- 文件对象
1.
2.
3.
4.
- 超级块对象
4.3.5 分区和安装
L i n u x 分区 { 引导块 超级块 若干 i 结点 文件数据块 \mathrm{Linux分区}\left\{\begin{aligned} &引导块\\ &超级块\\ &若干i结点\\ &文件数据块\\ \end{aligned}\right. Linux分区⎩ ⎨ ⎧引导块超级块若干i结点文件数据块
第五章 输入/输出(I/O)管理
5.1 I/O管理概述
5.1.1 I/O设备
- 定义:将数据输入输出计算机的外部设备
- 分类
- 信息交换单位
- 块设备:信息交换以数据块为单位。是有结构设备,如磁盘。效率高,可寻址
- 字符设备:信息交换以字符为单位。是无结构设备,如打印机。效率低,不可寻址,并且采用中断I/O
- 传输速率
- 低速设备:每秒几字节到数百字节,如鼠标、键盘
- 中速设备:每秒千字节到数万字节,如激光打印机
- 高速设备:每秒百千字节到千兆字节,如磁盘、光盘机
- 信息交换单位
- I/O接口
- I/O接口(设备控制器)位于CPU与设备之间,需要同两者通信,还要有按CPU的命令去控制设备工作的功能
- 设备控制器与CPU 的接口
- 三线:数据线、地址线和控制线
- 数据线通常与数据存储器和控制/状态寄存器相连
- 设备控制器与设备的接口
- 一个设备控制器可连接一个或者多个设备
- 每个接口存在数据、控制和状态三种类型的信号
- I/O逻辑
- 用于实现对设备的控制
- 通过一组控制线与CPU 交互,对从CPU 收到的I/O命令进行译码
- CPU 启动设备时,指令通过控制线、地址通过地址线发给控制器
- 由控制器的I/O逻辑对地址进行译码,并控制所选设备
- 功能
- ①接收和识别CPU 发来的指令,如磁盘控制器能接收读、写、查找等指令
- ②数据交换,包括设备和控制器之间的数据传输,以及设备控制器和主存之间的数据传输
- ③标识和报告设备状态,以供CPU 处理
- ④地址识别
- ⑤数据缓冲
- ⑥差错控制
- I/O端口
- 定义:I/O端口是值设备控制器中可以被CPU 之间访问的寄存器
- 分类
- 数据寄存器:实现CPU 和外设之间的数据缓冲
- 状态寄存器:获取执行结果和设备的状态信息,已让CPU知道是否准备好
- 控制寄存器:由CPU写入,以便启动指令和更改设备模式
- 通信方法
- 目的:实现CPU和I/O端口进行通信
- 独立编址
- 为每个端口分配一个I/O端口号,所有I/O端口形成I/O端口空间
- 用户不能对其进行访问,只有操作系统使用特殊的I/O指令才能访问端口
- 统一编址
- 又称内存映射I/O
- 每个端口被分配唯一的内存地址,且不会由内存被分配这一地址
- 通常分配给端口的地址靠近地址空间的顶端
5.1.2 I/O控制方式
完成一次读/写的过程 | CPU干预频率 | 每次I/O的数据单位 | 数据流向 | 优缺点 | |
程序直接控制方式 | CPU发出I/O指令后需要不断轮询 | 极高 | 字 | 设备→CPU→内存 内存→CPU→设备 | 每一个阶段的优点都是解决了上一阶段的最大缺点。总体来说,整个发展过程就是要尽量减少CPU对I/O过程的干预,把CPU从繁杂的I/O控制事务中解脱出来,以便更多地去完成数据处理任务。 |
中断驱动方式 | CPU发出I/O命令后可以做其他事,本次I/O完成后设备控制器发出中断信号 | 高 | 字 | 设备→CPU→内存 内存→CPU→设备 | |
DMA方式 | CPU发出l/O命令后可以做其他事,本次I/O完成后DMA控制器发出中断信号 | 中 | 块 | 设备→内存 内存→设备 | |
通道控制方式 | CPU发出I/O命令后可以做其他事。通道会执行通道程序以完成I/O,完成后通道向CPU发出中断信号 | 低 | 一组块 | 设备→内存 内存→设备 |
5.1.3 I/O软件层次结构
I/O层次结构 |
---|
用户层I/O软件 |
设备独立性软件 |
设备驱动程序 |
中断处理程序 |
硬件 |
- 用户层I/O软件
- 实现与用户的接口
- 用户在用户层调用与I/O相关的库函数,对设备进行操作
- 用户层软件必须通过一组\textbf{系统调用}来获取操作系统服务
- 设备独立性软件
- 作用:实现用户程序和设备驱动器的统一接口、设备命令,设备保护和设备分配释放
- 实现
- 引入逻辑设备和物理设备概念
- 用逻辑设备名来请求使用某类设备;
- 实际执行时,必须将逻辑设备名映射称物理设备名使用
- 好处
- ①增加设备分配的灵活性
- ②易于实现I/O重定向
- (设备可更换,不必更改应用程序)
- 功能
- ①执行所有设备的共有操作
- 对设备的分配和回收
- 将逻辑设备名映射为物理设备名
- 对设备进行保护,禁止用户直接访问设备
- 缓冲管理
- 差错控制
- 提供独立于设备的大小统一的逻辑块
- (屏蔽了设备之间信息单位大小的传输速率的差异)
- ②向用户层提供统一接口
- 无论何种设备,向用户提供的接口一个是相同的
- (比如对各种设备的读/写,统一的read/write)
- ①执行所有设备的共有操作
- 设备驱动程序
- 待续
- 中断处理程序
- 作用:保存CPU环境,转入相应的中断处理程序,恢复现场,返回进程
- 主要任务
- 进行进程上下问的切换
- 对处理中断信号源进行测试
- 读取设备状态和修改进程状态
串联例子:
①当用户要读取某设备的内容时,通过操作系统提供的命令接口,这就经过了用户层
②操作系统提供给用户使用的接口,一般是统一的通用接口,这就涉及到了设备独立性软件。
③不同设备对相同指令,会由不同的行为,这就需要设备驱动层。
④命令解析完成之后,就需要中断正在运行的程序,这就涉及了中断处理程序。
⑤最后,命令抵达硬件设备,完成相应功能
5.1.4应用程序I/O接口
- 字符设备接口
- 字符设备定义见5.1.1
- get和put操作:由于不可寻址,只能顺序存取
- in-control指令:包含许多参数,每个参数表示一个于具体设备相关的特定功能
- 属于独占设备,需要提供打开关闭功能,以实现互斥
- 块设备接口
- 块设备定义见5.1.1,如磁盘
- 磁盘设备的I/O通常采用DMA方式
- (磁盘扇区的地址由磁道号和扇区号组成)
- 隐藏了磁盘的二维结构,将所有扇区编号
- 将抽象命令映射为低层操作:将上层发来的操作命令映射为设备能识别的低层具体操作
- 内存映射数组通过内存的字节数组来访问磁盘,而不提供读/写磁盘操作
- 网络设备接口
- 提供面向网络的功能
- 许多网络I/O接口采用网络套接字
- 阻塞/非阻塞I/O
- 阻塞I/O:用户调用I/O操作时,进程被阻塞,需要等待I/O操作完成,进程才会被唤醒继续执行
- 非阻塞I/O:用户进程调用I/O操作时,不阻塞该进程,该I/O调用返回一个错误返回值,进程轮询查询I/O是否完成
5.2设备独立性软件
5.2.1与设备无关的软件
与设备无关的软件是I/O 系统的最高层软件,下层是设备驱动程序,其间的界限因操作系统和设备的不同有些差异
(确实只有这么短)
设备的分配方式:独享分配,共享分配,虚拟分配。
5.2.2高速缓存与缓冲区
- 磁盘高速缓存
- 使用磁盘高速缓存提高磁盘I/O 的速度
- 逻辑上属于磁盘,物理上是驻留在内存的盘块
- 形式
- 在内存中开辟一个单独的空间作为磁盘高速缓存,大小固定
- 把未利用的捏村空间作为一个缓冲池,供请求分页系统和磁盘I/O 共享
- 缓冲区
- 目的
- 缓和CPU与I/O 设备见速度不匹配的矛盾
- 减少对CPU的中断频率,放宽对CPU中断时间的限制
- 解决基本数据单元大小(即数据粒度)不匹配的问题
- 提高CPU与I/O 设备之间的并行性
- 实现方法
- 采用硬件缓冲器。成本太高,关键部位才使用
- 采用缓冲区(内存区域)
- 单缓冲
- 主存中设置一个缓冲区。用于设备和处理机交换数据
- I / O 设备 ⟶ 输入 缓冲区 ⟶ 传送 工作区(处理) I/O 设备\stackrel{输入} \longrightarrow 缓冲区 \stackrel{传送} \longrightarrow 工作区(处理) I/O设备⟶输入缓冲区⟶传送工作区(处理)
- 输入和传送互斥,传送和处理互斥
- t i m e = m a x ( 输入 + 传送,处理 + 传送 ) = m a x ( 输入,处理 ) + 传送 \mathrm{time=max(输入+传送,处理+传送)=max(输入,处理)+传送} time=max(输入+传送,处理+传送)=max(输入,处理)+传送
- 双缓冲
- 两个缓冲区\
- I / O 设备 ⟶ 输入 缓冲区 1 ;缓冲区 2 ⟶ 传送 工作区(处理) I/O 设备\stackrel{输入}\longrightarrow 缓冲区1;缓冲区2\stackrel{传送} \longrightarrow 工作区(处理) I/O设备⟶输入缓冲区1;缓冲区2⟶传送工作区(处理)
- 传送和处理互斥
- t i m e = m a x ( 输入,处理 + 传送 ) \mathrm{time=max(输入,处理+传送)} time=max(输入,处理+传送)
- 循环缓冲
- 多个大小相等的缓冲区
- 每个缓冲区有个指向下个缓冲区的指针,最后一个指向第一个
- 还有两个指针in、out用于指向输入输出
- 缓冲池
- 由多个系统公用的缓冲区组成
- 分三个队列:空缓冲队列、输入队列、输出队列
- 四个缓冲区
- 用于收容输入数据的工作缓冲区
- 用于提取输入数据的工作缓冲区
- 用于收容输出数据的工作缓冲区
- 用于提取输出数据的工作缓冲区
- 机理:待续
- 目的
- 对比
高速缓存 | 缓冲区 | ||
相同点 | 都介于高速设备和低速设备之间 | ||
区别 | 存放数据 | 存放的是低速设备上的某些数据的复制数据,即高速缓存上有的,低速设备上面必然有 | 存放的是低速设备传递给高速设备的数据(或相反),而这些数据在低速设备(或高速设备)上却不一定有备份,这些数据再从缓冲区传送到高速设备(或低速设备) |
目的 | 高速缓存存放的是高速设备经常要访问的数据,若高速设备要访问的数据不在高速缓存中,则高速设备就需要访问低速设备 | 高速设备和低速设备的通信都要经过缓冲区,高速设备永远不会直接去访问低速设备 |
5.2.3 设备分配与回收
- 设备特性
- 独占设备
- 共享设备
- 虚拟设备
- 数据结构
- 设备控制表DCT
- 每个设备对应一张DCT
- 关键字段
- 类型
- 标识符
- 状态
- 指向COCT的指针的等待队列
- 控制器控制表COCT
- 每个控制器对应一张COCT
- 关键字段
- 状态
- 指向CHCT的指针
- 等待队列指针
- 通道控制表CHCT
- 每个控制器对应一张CHCT
- 关键字段
- 状态
- 等待队列
- 系统设备表SDT
- 记录整个系统所有设备的情况
- 每个设备对应一个表目
- 关键字段
- 设备类型
- 标识符
- DCT
- 驱动程序入口
- 设备控制表DCT
- 设备分配策略
- 原则:充分发挥使用效率,同时不死锁,还要程序和设备分开
- 方式
- 静态分配:进程运行前为其分配全部所需资源,运行结束后归还
- 动态:进程运行过程中动态申请设备资源
- 算法:先来先服务,优先级高者优先等
- 独占设备一般采用静态分配方式,共享设备一般采用动态分配方式
- 安全性
- 指避免进程死锁
- 安全分配方式
- 每当进程发出I/O 请求后阻塞,直到I/O 操作完成完成唤醒
- 阻塞时不保持任何资源
- 优点:设备分配安全
- 缺点:CPU和I/O 是串行工作
- 不安全分配方式
- 进程发出I/O 请求后继续运行,可以发出下一个I/O 请求
- 只有当请求的设备被占用时才阻塞
- 优点:进程可以操作多个设备,进程推进迅速
- 缺点:有可能造成死锁
- 改进
- 用户编程时使用逻辑设备名单申请设备,系统负责映射(逻辑设备表LUT)
- LUT设置
- 整个系统一张LUT
- 每个用户一张LUT
5.2.4 SPOOLing技术(假脱机技术)
- 目的:缓和CPU的高速性与I/O设备低速性之间的矛盾
- 定义:是采用的一项将独占设备改造成共享设备的技术
- 输入井输出井
- 在磁盘开辟出的两个存储区域
- 输入井模拟脱机输入的磁盘,用于收容I/O设备输入的数据
- 输出井模拟脱机输出的磁盘,用于收容用户程序的输出数据
- 输入(输出)缓冲区
- 在内存中开辟的两个缓冲区
- 输入缓冲区暂存输入设备送来的数据,后传至输入井
- 输出缓冲区暂存输出井送来的数据,后传至输出设备
- 特点
- ①提高了I/O速度,缓和了CPU和低速I/O之间的速度
- ②将独占设备改造位共享设备
- ③实现了虚拟功能
5.2.5 设备驱动程序接口
待续
5.3磁盘和固态硬盘
5.3.1 磁盘
5.3.2 磁盘管理
5.3.3 磁盘调度算法
-
寻找时间
T
s
寻找时间T_s
寻找时间Ts
跨越每条磁道时间 m ,跨越 n 条磁道,启动振臂时间 s 跨越每条磁道时间m,跨越n条磁道,启动振臂时间s 跨越每条磁道时间m,跨越n条磁道,启动振臂时间s
T s = m ∗ n + s T_s=m*n+s Ts=m∗n+s - 旋转延迟时间
T
r
T_r
Tr
频率 f ( 单位 : 转 / s ) 频率f (单位:转/s) 频率f(单位:转/s)
T r = 1 2 f T_r=\cfrac{1}{2f} Tr=2f1 - 传输时间
T
t
T_t
Tt
需要读写的字节数 b ,磁盘旋转速 f , N 每个磁道的字节数 需要读写的字节数b,磁盘旋转速f,N每个磁道的字节数 需要读写的字节数b,磁盘旋转速f,N每个磁道的字节数
T t = b f N T_t=\cfrac{b}{fN} Tt=fNb -
总时间
T
a
总时间T_a
总时间Ta
T a = 寻找时间 T s + 旋转延迟时间 T r + 传输时间 T t T_a=寻找时间T_s+旋转延迟时间T_r+传输时间T_t Ta=寻找时间Ts+旋转延迟时间Tr+传输时间Tt
T a = ( m n + s ) + 1 2 f + b f N T_a=(mn+s)+\cfrac{1}{2f}+\cfrac{b}{fN} Ta=(mn+s)+2f1+fNb