操作系统
目录1
概念
命令接口
- 联机命令接口:说一句做一句
- 脱机命令接口:说一堆做一堆
特征
- 并发:微观交替,宏观同时;(另:并行 多核CUP)
- 共享
- 互斥共享:系统中某些资源一段时间只允许一个进程访问(摄像头)
- 同时共享(发文件)
- 虚拟(3G内存 同时运行远大于3G)
- 时分复用
- 空分复用
- 异步:进程的执行不是一贯到底
操作系统的发展
单道批处理系统
- 监督程序负责脱机输入/输出,输出完成才读入第二个
- CPU资源利用率低
多道批处理系统
- 并发执行
- 缺点:没有人机交互,无法调剂
分时操作系统
- 以时间片为单位轮流服务,及时响应
- 缺点:不能优先响应紧急任务
实时操作系统
- 紧急任务优先响应
- 硬实时操作/软实时操作
运行机制
- 应用程序/内核程序
- 特权指令/非特权指令
- 用户态 目态/内核态 管态
- 程序状态字寄存器(PSW)
- 如何变态
中断和异常
- 没有中断就没有并发
- 类型
- 内中断(异常):故障(如在用户态执行特权指令,内核可修复);陷入指令(系统调用);终止(内核无法修复)
- 外中断(狭义的中断):时钟中断;I/O中断;每个指令末尾检查。
- 中断向量表
系统调用
- 使上层程序能够请求内核的服务
- 和共享资源有关的操作需要进行系统调用
- 传递系统调用参数 -> 陷入指令(用户态) -> 执行相应程序处理(核心态) -> 返回应用程序
操作系统体系结构
内核
- 大内核/微内核
操作系统引导
-
开机过程
虚拟机
2
进程
- PID 不重复的 唯一的 标志
- PCB 进程控制块 进程存在的唯一标志;给操作系统用的
- 程序段、数据段:给进程自己用的,与进程自身运行逻辑有关
进程的状态与转换
原语
- 原子性
- 特权指令:关中断指令 开中断指令
- 常见:创建原语、撤销原语、阻塞原语、唤醒原语
进程通信(IPC)
简介
-
共享存储
- 基于存储区,访问互斥,高级;
- 基于数据结构,特殊的全局变量,低级。
-
消息传递:格式化的Message(消息头,消息体);发送原语,接收原语。
- 直接通信:指明接收进程的ID。
- 间接通信:指明信箱。
- 管道通信:半双工通信;互斥访问(操作系统实现);同一段时间内单向的数据流(类似队列 先进先出),一头写数据一头读数据;pipe文件;本质上是在内存中开辟一个大小固定的内存缓冲区;管道中的数据一旦被读出就彻底消失(多个写一个读);
线程
概念
- 线程是一个基本的CPU执行单元,是程序执行流(调度)的最小单位。
- 进程是资源分配的最小单位。
- 一个进程中可以有几个线程。
- 只有内核级线程是处理机分配的单位
实现方式
-
用户级线程:线程库;用户态下完成。
-
优点:不用变态,开销小、效率高。
-
缺点:一个阻塞,整个阻塞;并发度不高;多个线程不可在多核处理机运行。
-
-
内核级线程
- 优点:并发能力强。
- 缺点:cpu变态多,线程管理成本高。
-
多线程模型
-
一对一:并发能力强。管理开销大。
-
多对一:并发性低。管理开销小。
-
多对多(n>=m)
-
线程的状态与转换 组织与控制
- 就绪、运行、阻塞
- 线程表
处理机调度
- 高级调度:作业调度。
- 低级调度:进程调度/处理机调度;最基本的调度;频率高。
- 中级调度:内存调度;挂起状态的进程重新进入内存。
- 七状态模型:就绪挂起、阻塞挂起;挂起态进程映像在外存,阻塞态在内存。
进程调度的时机、切换与过程
-
主动放弃;被动放弃。
-
不能进行进程切换:中断处理过程中;操作系统内核程序临界区(区分普通临界区)中;原子操作过程中。
-
临界资源:一段时间仅允许一个进程使用
-
方式:非剥夺调度方式/剥夺调度方式
-
进程切换:对原来进程数据保存,对新进程数据恢复;
调度器和闲逛进程
-
触发调动程序:创建新进程;进程退出;运行进程阻塞;I/O中断发生。
-
支持内核级线程:处理对象是内核线程;不支持内核级进程:处理对象是进程。
-
闲逛进程:没有其他就绪进程时运行闲逛进程。优先级最低;0地址指令;能耗低。
调度算法
评价指标
-
CPU利用率 = 忙碌的时间/总时间
-
系统吞吐量 = 总共完成的作业数/总共花的时间
-
周转时间 = 作业在后备队列等待作业调度的时间 + 进程在就绪队列上等待调度(低级调度)的时间 + 进程在CPU上执行的时间 + 进程等待I/O操作完成的时间
= 作业完成时间 - 作业提交时间
-
平均周转时间 = 各作业周转时间之和/作业数
-
带权周转时间 = 周转时间/ 运行的时间
-
平均带权周转时间
-
等待时间 :
- 进程:周转时间 - 运行时间 - I/O操作时间
- 作业:不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间。
-
响应时间:提出请求到首次产生响应所用的时间。
调度算法(1)
先来先服务(FCFS):考虑等待时间
- 规则:按作业到达后备队列的先后顺序;按进程到达就绪队列的先后顺序。
- 作业/进程调度。
- 非抢占式。
- 优缺点
- 优点:公平;算法实现简单。
- 缺点:对长作业有利、短作业不利(排在后面的短作业带权周转时间大)
- 不会导致饥饿
短作业优先(SJF):考虑执行时间
- 规则:选择当前已经到达的且运行时间最短的作业/进程 。
- 作业/进程调度。
- SJF和SPF是非抢占式算法, SRTN(最短剩余时间优先算法)是抢占式。
- SRTN:当有新进程加入就绪队列时就需要调度,如果新进程的剩余时间比当前运行的进程剩余时间更短,则新进程抢占处理机。
- SRTN 平均等待时间、平均周转时间最短
- 优缺点:
- 优点:用时短
- 缺点:不公平,对短作业有利长作业不利;不一定真实。
- 长作业饥饿
高响应比优先(HRRN)
- 规则:响应比最高。响应比 = (等待时间+要求服务时间)/要求服务时间 。
- 作业/进程调度。
- 非抢占式。
- 优点:综合考虑上面两种。
- 不会导致饥饿。
调度算法(2)
时间片轮转(RR)
- 规则:轮流执行一个时间片(过大:退化成先来先服务;过小:进程切换频繁)。
- 进程调度。
- 抢占式;时钟中断。
- 优缺点
- 优点:公平;响应快,适用于分时操作系统。
- 缺点:进程切换有开销;不区分紧急程度。
- 不会饥饿。
优先级调度算法
-
规则:先优先级高。
-
作业/进程。
-
抢占式/非抢占式。
-
静态优先级:创建进程时确定,之后不变。
动态优先级:动态调整优先级。
-
通常系统进程高于用户进程;前台进程高于后台进程;操作系统更偏好I/O繁忙型进程(相对的是CPU繁忙型进程)。
多级反馈队列调度算法
- 抢占式算法
- 可能饥饿
调度算法(3)
多级队列调度算法
- 优先级:系统进程> 交互式进程> 批处理进程(举例)
- 队列间采取固定优先级,或不同的时间片划分
- 各个队列采取不同的调度策略
进程同步、互斥
- 进程同步:协调进程间的相互制约关系,使按照预期方式执行
- 进程互斥 两种相互制约形式:
- 直接(互斥(狭义)):进程排他性访问共享资源
- 间接(同步(狭义)):进程间的合作(比如管道通信)
(重要)软件实现互斥的方法
-
访问过程:
- 进入区:成功则加锁(lock)
- 临界区:访问
- 退出区:解锁(unlock),唤醒其它阻塞进程
- 剩余区:其他代码
-
访问原则:空闲让进(先来先进);忙则等待;有限等待;让权等待
-
软件实现
-
单标志法:违背 ”空闲让进“(必须要求两个进程交替访问,当一个不访问时另一个无法访问)
-
双标志法:先检查再赋值;违背 “忙则等待”。主要原因:检查和赋值不是一气呵成!
-
双标志法后检查:先赋值后检查;违背 “空闲让进”、“有限等待”。
-
皮特森算法:争取,谦让,检查对方和是否自己后谦让。违背“让权等待”,会发生“忙等”
-
硬件实现互斥的算法
-
中断屏蔽:关中断/开中断
- 关中断可能会被滥用
- 关中断时间长影响效率
- 不适用于多处理机,无法防止其它处理机调度其它进程访问临界区
- 只适用于内核进程
-
TS指令/TSL指令
- 原子操作
- 违背“让权等待”,会“忙等”
-
Swap指令
- 原子操作
- 违背“让权等待”
互斥锁
- 自旋锁
- 忙等
- 多用于多处理机系统
信号量
- 通过操作系统提供的一对原语来对信号量进行操作 PV操作
- 信号量:表示系统中某种资源的数量
整型信号量
记录型信号量
- 带samaphore
- 进程同步:前V后P
典型问题
生产者 消费者问题
- 缓冲区:互斥地访问
多(种)生产者 消费者问题
-
拆:从“事件”角度考虑
吸烟者问题
- 供货商提供三种材料给三个人
- 桌上每次只摆一种材料
读者写者问题
- 互斥:写写 写读
- 读读 不互斥
哲学家进餐问题
- 区别:每一个哲学家都需要持有两个临界资源才能吃饭
- 解决死锁问题
管程
定义
-
组成(类似与面向对象中的“类”)
- 局部于管程的共享数据结构说明
- 对该数据结构进行操作的一组过程
- 对局部于管程的共享数据设置初始值的语句
- 管程有一个名字
-
注意:每次仅允许一个进程或线程在管程内执行某个内部过程
-
(大概就是把PV操作的进程都交给管程内部处理,由编译器负责实现各进程互斥的进入管程中的过程,程序员只需要调用管程中提供的方法)
死锁
- 必备条件
- 互斥条件
- 不可剥夺条件
- 请求和保持条件
- 循环等待条件
死锁的处理
静态策略:预防死锁
破坏必备条件
-
把互斥的资源改造为共享资源
-
破坏不剥夺条件(复杂,造成之前工作失效,降低系统开销,会全部放弃、导致饥饿)
-
方案1:当请求得不到满足的时候,立即释放手里的资源
-
方案2:由系统介入,强行帮助剥夺
-
-
破坏请求和保持条件(资源利用率极低,可能会导致某些进程饥饿)
- 采用静态分配方法,一次性全部申请,如果申请不到,不要允许
-
破坏循环等待条件(不方便增加新的设备,实际使用与递增顺序不一致,会导致资源的浪费,必须按规定次序申请资源)
- 顺序资源分配法:对资源编号,进程按编号递增顺序请求资源
动态策略:避免死锁
安全序列 安全状态
- 有安全序列 - > 安全状态
- 如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁(处于不安全状态未必就是发生了死锁,但发生死锁时一定时在不安全状态)
银行家算法
初始分配完成后,优先全部分配给最少的,并且拿回资源
1、检查此次申请是否超过了之前声明的最大需求数
2、检查此时系统剩余的可用资源是否还能满足这次请求
3、试探着分配,更改各数据结构
4、用安全性算法检查此次所分配是否会导致系统进入不安全状态
死锁的检测和解除
死锁的检测
-
用某种数据结构来保存资源的请求和分配信息
-
提供一种算法,利用上述信息来检测系统是否已进入死锁状态
死锁的解除
-
资源剥夺法(放到外存):挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。
-
撤销进程法(终止进程法):强制撤销部分,甚至全部死锁进程,并剥夺这些进程的资源。
-
进程回退法:让一个或多个死锁进程回退到足以避免死锁的地步。
3.1
内存
- 程序需要放到内存中才能被CPU处理
- 存储单元:每个地址对应一个存储单元
指令的工作原理
- 逻辑地址vs物理地址:逻辑地址是相对地址
- 从写程序到程序运行:编辑-编译-链接(确定完整的逻辑地址)-装入(确定物理地址)
三种装入方式
- 绝对装入:在编译时产生绝对地址
- 静态重定位:装入时将逻辑地址转表为物理地址,程序运行期间不可移动
- 动态重定位(现在):把地址转化推迟到程序真正要执行时才进行,允许移动,需要设置重定位寄存器(记录进程的起始物理地址)
三种链接方式
- 静态链接:在程序运行前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件
- 装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式
- 运行时动态链接:在程序执行中需要该模块时,才对它进行链接,其优点时便于修改和更新。
内存管理
-
内存空间的分配与回收
-
内存空间的扩充
- 内存的虚拟性
-
地址转换
- 逻辑地址和物理地址转换 - > 三种装入方式
-
内存保护:各进程只能访问自己的内存单元
- 设置上下限寄存器
- 采用重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器)
覆盖与交换
-
覆盖技术(早期):固定区/覆盖区,需要常驻的放在”固定区“,调入后就不再调出,不常用的段放在”覆盖区“,需要用到时调入内存,用不到时调出
-
同一个程序或进程
-
缺点:对用户不透明
-
-
交换技术(中级调度):内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(PCB会常驻内存,不会被换出)
- 不同的进程(作业之间)
-
磁盘:文件区(离散分配)/对换区(连续分配)
连续分配管理方式
-
单一连续分配:内存被分配为系统区和用户区,系统区在低地址,同一时间只能有一道用户程序(不并发),用户区是一个用户独享
- 优点:简单,无外部碎片
- 缺:只能用于单用户、单任务操作系统,有内部碎片
-
固定分区分配:将用户区分割为若干固定分区给各道程序
- 分割策略有分区大小相等/不相等,分区说明表(管理各个分区)
- 无外部碎片
- 有内部碎片
-
动态分区分配:进程装入内存时,根据进程的大小动态地建立分区。
- 空闲分区表/链
- 有外部碎片
- 无内部碎片
-
内部碎片:已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;
-
外部碎片:还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
- 紧凑技术:进程空间复制转移
动态分区分配算法
基本分页存储管理
- 概念
- 页框/页帧/内存块/物理块/物理页面:内存
- 页/页面:进程
- 页表:记录页面和内存块之间的映射关系(进程的页面与内存的页框一一对应);页号隐含,块号3字节
- 注意:页表存放的是块号,内存块起始地址 = 块号*内存块大小
- 页面大小为2^k B,用二进制数表示逻辑地址,末位k位为页内偏移量,其余部分是页号
基本地址变换机构
- 页表寄存器(PTR):存放页表在内存中的起始地址F和页表长度M,进程未执行时,页表的起始地址和页表的长度放在进程控制块(PCB)中,当进程被调度时,操作系统内核会把它们放在页表寄存器中。
具有快表的地址变换机构
- 高速缓存
- 快表(TLB):又称联想寄存器,是一种访问速度比内存快很多的高速缓冲存储器,存放最近访问的若干页表项的副本,以加速地址变换的过程。与此对应,内存中的页表常称为慢表。
- 局部性原理
- 时间局部性:访问某个变量后,在不久的将来还会被访问
- 空间局部性:程序访问了某个存储单元,不久之后,其附近的存储单元也很有可能被访问
两级页表
单级页表存在的问题
-
所有页表项必须连续存放,页表过大时需要很大的连续空间
-
在一段时间内并非所有页面都用得到,因此没必要让整个页表常驻内存
两级页表
- 将长长的页表再分页
- 逻辑地址结构:(一级页号、二级页号、页内偏移量)
- 页目录表/外层页表/顶级页表
细节
- 多级页表中,各级页表的大小不能超过一个页面。若两级页表不够,可以分更多级
- 多级页表的访问次数(假设没有快表结构)——N级页表访问一个逻辑地址需要N+1次访存
基本分段存储管理方式
分段
-
进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每段有段名,每段从0开始编址
-
段号的位数决定了每个进程最多可以分几个段
-
段内地址位数决定了每个段的最大长度是多少
段表
- 段表:段号 段长 基址
- 各段表项的长度是相同的
地址变换
- 和分页最大的区别:段长不一样,需要多判定一次段内地址是否大于段长
分段、分页管理的对比
-
页:信息的物理单位,实现离散分配,提高内存利用率;用户不可见;地址是一维的,访存2次;
-
段:信息的逻辑单位,对用户可见;地址是二维的(段名+段内地址),访存3次
-
分段比分页更容易实现信息的共享和保护
- 因为分页不是按逻辑划分,某段需要被访问的内容可能分开在两页
-
(不能被修改的代码称为纯代码和可重入代码,不属于临界资源)
优缺点
-
分页:利用率高,碎片少,不方便进行信息共享和保护
-
分段:方便信息共享和保护,如果段长大,容易产生外部碎片
段页式管理
-
先分段再分页
-
段号 + 段内地址(页号+页内偏移量)
-
地址结构是二维的
-
段表、页表
地址变换
- 三次访存
- 可用快表
3.2
传统
- 一次性:作业必须全部装入内存后才能开始运行;并发性下降
- 驻留性:一旦作业被装入内存,就会一直驻留在内存
虚拟内存
-
局部性原理:时间局部性、空间局部性
-
多次性、对换性、虚拟性
-
请求调页(段)、页面(段)置换
请求分页
-
访问信息不在内存时,操作系统从外调入
-
页表机制:内存块号 状态位 访问字段 修改位 外存地址
-
缺页中断机构:调页完成后再将进程唤醒;内中断(故障),可被修复
页面置换算法
-
最佳置换算法(OPT optimal)
- 每次选择淘汰的页面是以后永不使用或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率。
- 实际上不知道后面的序列
-
先进先出置换算法(FIFO)
- 每次选择淘汰的页面是最早进入内存的页面
- Belady异常,当分配的内存块增大时,缺页次数反而增加
-
最近最久未使用置换算法(LRU)
- 每次淘汰往前数最近最久未使用的页面
- 硬件支持,开销大,实现困难
-
时钟置换算法(最近未用算法,CLOCK,NRU)
- 简单的:扫一次,为1的置零,踢0;最多经历两轮扫描(全为1)
- 改进型的时钟置换算法:优先淘汰没有被修改过的,因为没有修改 过的不用进行IO操作;访问位+修改位,最多4轮
- 顺序:00, 01, 10, 11
页面分配策略
-
驻留集:指请求分页存储管理中给进程分配的物理块的集合
-
页面分配、置换策略
- 固定分配局部替换:驻留集大小不可改变
- 可变分配全局替换:可以将操作系统保留的空闲物理块分配给缺页进程,若无,则换出未锁定的页面;只要缺页就会分配新的物理块;
- 可变分配局部替换:只能选进程自己的物理块置换;通过缺页的频率动态增加或减少进程的物理块;
调入页面的时机
- 预调页策略:一次调用若干个相邻页面,运行前调入
- 请求调页策略:运行时缺页再调入
从何处调页
-
对换区:快,采用连续分配方式
-
文件区:慢,采用离散分配方式
抖动、工作集
-
抖动(颠簸)现象:刚刚换出的又要换入,刚刚换入的又要换出(物理块不够)
-
工作集:指在某段时间间隔(窗口)里,进程实际访问页面的集合
-
一般驻留集 >= 工作集
内存映射文件
- 系统调用,将文件映射到虚拟地址空间
- 程序员编程更简单
- 多进程可以映射同一个文件,实现共享
4.1
文件管理
-
文件属性:文件名,标识符,类型....
-
外存:分为磁盘块
文件的逻辑结构
无结构文件
-
流式文件
-
文件由一系列二进制文件流组成
有结构文件
- 记录式文件,每条记录由若干数据项组成(excel表)
顺序文件
文件中的记录一个接一个顺序排列,定长或变长,可以顺序存储或者链式存储;按照是否与关键字顺序有关,可以分为串结构和顺序结构
- 链式:无法随机存取
- 顺序存储:
- 可变长:无法随机存取
- 定长:可以随机存取;采用串结构,无法快速找到关键字;采用顺序结构,可以快速查找关键字
索引文件
-
多一个索引表,检索速度快
-
索引表本身是定长记录的顺序文件
索引顺序文件
- 把记录分组,一组记录对应一个索引表项
- 多级索引表嵌套查找
文件目录(重要)
文件控制块(File Control Block,FCB)
- 相当于目录
- 包括文件基本信息:文件名,存放地址,读写等
- 操作:搜索、创建文件、删除文件、显示目录、修改目录
目录结构
单级目录结构
- 不允许重名
两级目录结构
- 主文件目录(MFD)+用户文件目录(UFD)
- 可以重名,访问限制
多级目录结构(树形目录结构)
-
多级分类
-
不方便共享
-
当代操作系统采用方法、不便于文件共享
无环图目录结构
- 可以用不同的文件名指向同一个文件
- 共享计数器
- 可以共享
索引节点
-
对文件控制块FCB的改进
-
目录项只包含文件名,索引结点和指针
文件的物理结构(文件分配方式)
连续分配
- 文件目录存放起始块号和长度
- 顺序访问/直接访问
- 顺序读取速度最快
- 拓展不方便
- 有很多磁盘碎片
链接分配(指针)
- 隐式分配(默认)
- 存放起始块号和结束块号
- 只支持顺序访问,不支持随机访问,方便拓展
- 显示分配
- 文件分配表FAT file allocation table
- 目录记录起始块号,指针放在FAT中
- 方便拓展,支持随机访问
- 文件表会占内存空间
索引分配
-
离散地分配,索引表记录文件的各个逻辑块对应的物理块
-
支持随机访问,容易拓展
-
索引表太大
- 链接方案
- 多层索引
- 混合索引:(考点:根据顶级索引表的结构来计算最大文件长度)(好处:小文件就不用分多级)
-
疑问:显示链接分配和索引分配有什么区别?
-
回答:FAT表中是链接寻找,索引表中是直接寻找;对于显式链接来说,一个磁盘中只有一块FAT,而索引分配的话一个文件就有一个索引表。一个磁盘中含有多个文件就有多个索引表。
逻辑结构vs物理结构
文件存储空间管理
- 记录和组织空闲的磁盘块
存储空间的划分与初始化
- 文件卷
- 目录区,文件区
管理方法
-
空闲表法:首位置+长度,回收时注意修改
-
空闲链表法(空闲盘块链、空闲盘区链)
-
位示图法
-
成组链接法:文件卷的目录区中专门用一个磁盘块作为超级块(链头那个大块,每一个组被分配出去后,该组指向下一个组的链接信息将被保存在超级块上),当系统启动时需要将超级块读入内存。并且保证内存与外存中的超级块数据一致。
文件的基本操作
-
创建文件(create)
- 在外存中找到文件所需的空间
- 创建该文件对应的目录项
-
删除文件(delete)
- 找到文件名对应的目录项
- 回收文件占用的磁盘块
- 删除文件对应的目录项
-
打开文件(open)
- 找到文件名对应的目录项
- 将目录项复制到内存中的“打开文件表”中,并将索引号(文件描述符)返回给用户
- 打开文件表:进程(有系统表索引号),系统(总表)(有打开计数器)
-
关闭文件(close)
- 进程表中响应文件删除
- 系统计数器减1
-
读文件(read)
-
写文件(write)
文件共享
-
基于索引结点的共享方式(硬链接)
- 直接指向文件的索引节点:记录count和文件物理地址
- 不同目录指向同一节点
-
基于符号链的共享方式(软链接)
- Link类型的文件记录文件1的存放路径
- 相当于win的快捷方式
文件保护
-
口令保护
- 开销小
-
加密保护
- 保密性强,不需要在系统中存储“密码”
- 编码/译码,需要花费一定时间
-
访问控制
- 在每个文件的FCB中增加一个访问控制表(Access-Control List, ACL),该表记录了各个用户可以对该文件执行哪些操作
- 精简:以组为单位
4.3
文件系统的层次结构
文件系统的全局结构
-
物理格式化:划分扇区,检测坏扇区并用备用扇区替代
-
逻辑格式化:磁盘分区(分卷 Volume)
-
外存
-
内存结构:
虚拟文件系统(Virtual File System,VFS)
- 不同文件系统有不同的规范,需要向上提供统一标准的系统接口
- 特点
- 向上提供统一接口
- 要求下层文件系统必须实现某些规定函数功能
- 每打开一个文件都会新建一个Vnode(只存在于主存),用统一的数据结构表示文件,vnode中有函数功能指针
文件系统挂载 mounting
- 在VFS中注册新挂载的文件系统。内存中的挂载表( mount table)包含每个文件系统的相关信息,包括文件系统类型、容量大小等。
- 新挂载的文件系统,要向VFS提供一个函数地址列表
- 将新文件系统加到挂载点(mountpoint) ,也就是将新文件系统挂载在某个父目录下
5.1
I/O设备
- 机械部件(如鼠标键盘等)+电子部件(I/O控制器)
I/O控制器
- CPU和I/O设备之间的中介,实现设备对I/O设备的控制
-
一个I/O控制器可以控制多个设备,内有多个寄存器
-
寄存器编址
- 内存映像I/O:占用内存地址的一部分,和内存统一编址
- 寄存器独立编址:采用专用I/O地址,单独编址;缺点:需要设置专门的指令来操作控制器(指明操作哪一个控制器)
I/O控制方式
-
程序直接控制方式
- 轮询:轮训检查控制寄存器的状态,完成一次读/写操作的流程
- CPU干预频繁
- 每次读写一个字
- 优:实现简单
- 缺:会使CPU忙等
-
中断驱动方式
- 让cpu发出io指令后做其它的事情,I/O设备完成后向cpu发出中断信号
- cpu在每个指令周期末尾检查中断
- 大量中断会使cpu效率低
- 缺:每次读写一个字,中断多,效率低;读写都需要经过cpu中转
- 优:cpu和io可并行工作
-
DMA(Direct Memory Access)方式:直接存储器存取
- 数据单位:连续的多个块
- 直接从设备到内存
- 只在一个块开始或结束时才需要cpu,减少了cpu干预
- 每次读写一个或连续的多个块(读入内存后也要连续存放)
-
通道控制方式
- 通道:一种硬件,弱版cpu
- 通道程序:任务清单
- 每次读写一组数据块
- cpu发送命令给通道,然后让通道处理IO操作,处理完了,向cpu发送中断信号
- 实现复杂
I-O软件层次结构
-
用户层软件
- 实现与用户交互的接口,向上提供方便易用的库函数
-
设备独立性软件(设备无关性软件)
- 向上层提供统一的调用接口(read/write)
- 设备的保护
- 差错处理
- 设备的分配与回收
- 数据缓冲区管理
- 逻辑设备表(LUT):建立逻辑设备名到物理设备名的映射关系
- 根据设备类型选择调用相应的驱动程序
-
设备驱动程序(比如打印机驱动)
- 设置设备寄存器、检查设备状态
-
中断处理程序
- 进行中断处理
-
硬件
- 执行IO操作,有机械部件、电子部件组成
输入输出应用程序接口
阻塞/非阻塞IO
- 阻塞IO:发出IO系统调用请求后,需要阻塞态等待(如scanf)
- 非阻塞态IO:进程无须阻塞等待
统一标准的设备驱动接口
5.2
I-O核心子系统
-
用户层软件
- 假脱机技术(SPOOLing技术)
-
(重点)设备独立性软件(设备无关性软件)
- IO调度:按某算法确定IO请求的顺序
- 设备保护
- 设备分配与回收、缓冲区管理
-
设备驱动程序(比如打印机驱动)
-
中断处理程序
-
硬件
假脱机技术
-
脱机技术
- 脱离主机的控制进行输入/输出控制
- SPPOLing技术:必须要有多道程序并发进行
-
假脱机技术的实现原理
- 共享打印机的原理分析
- 独占式设备:只允许串行使用
- 共享设备:允许多个进程“同时”使用
- 假脱机文件队列
设备的分配与回收
-
固有属性:独占设备、共享设备、虚拟设备(采用SPOOLing把独占改造为共享)
-
设备分配算法
-
安全性
- 安全分配:为进程分配一个设备后就将进程阻塞,本次IO完成后才将进程唤醒。不会死锁。
- 不安全分配:进程和IO并行。可能死锁。
-
静态分配与动态分配
- 静态分配:进程运行前为其分配全部所需资源、运行结束后归还资源
- 动态分配:运行中动态分配
设备分配管理中的数据结构
-
树
-
设备控制表DCT:设备类型、设备标识符、设备状态、指向控制器表的指针、重复执行次数或事件、设备队列的队首指针
-
控制器控制表COCT:控制器标识符、控制器状态、指向通道表的指针设备队列的队首指针、控制器队列的队尾指针
-
通道控制表CHCT:通道标识符、通道状态、与通道连接的控制器表首址、通道队列的队首指针、通道队列的队尾指针
-
系统设备表SDT:记录系统中全部设备的情况,设备类型、设备标识符、DCT、驱动程序入口
设备分配
-
步骤:根据进程请求的物理设备名——>设备控制表——>控制器控制表——>通道
-
改进方法:建立逻辑设备名(指明逻辑设备名)和设备的映射表(LUT)
缓冲区管理
-
缓冲区:一个存储区域
- 缓和CPU与IO设备之间速度不匹配的矛盾
- 减少对CPU的中断频率
- 解决数据粒度不匹配的问题
- 提高CPU与IO设备之间的并行性
-
单缓冲
- 在内存中分配一块缓冲区
- 当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出;当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区充满以后,才能从缓冲区把数据传出。
- 处理一块时间 = max(C,T)+M
-
双缓冲
- 在内存中分配两块缓冲区
- 分T>C+M和T<C+M,max(T,C+M)
-
单双缓冲在通信中的区别
-
循环缓冲
- in指针指向下一个空,out指向下一个慢的
-
缓冲池(就是一堆各种各样的缓冲区)
- 由系统中共用的缓冲区组成
- 这些缓冲区可以分为:空缓冲队列、装满输入数据的缓冲队列、装满输出数据的缓冲队列
5.3
磁盘的结构
-
磁盘、磁道、扇区
-
每个扇区存输的数据量相同,最内侧面积最小数据密度最大
-
盘面、柱面
- 所有磁头共进退,用哪个就激活哪个
-
(柱面号,盘面号,扇区号)可定位一个“磁盘块”
-
分类:固定头/移动头,固定盘/可换盘
磁盘调度算法
-
一次磁盘读/写操作需要的时间
-
寻找时间 Ts=s+m*n ( 启动磁头臂时间s,每跨越一个磁道时间m,总共需要跨越n)
-
延迟时间 Tr= 1/(2r) (转速r,单位:转/秒)
-
传输时间Tt=b/(rN)
-
磁盘调度算法
-
先来先服务(FCFS)
-
最短寻找时间优先(Shorttest Seek Time First,SSTF)
- 优先处理最近的磁道,可能会产生饥饿现象
-
扫描算法(SCAN)
- 只有磁头移动到最外侧磁道的时候才能往内移动,移动到最内侧磁道的时候才能往外移动
-
LOOK
- (在SCAN基础上)如果在磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向
-
循环扫描算法(C-SCAN)
- 返回时直接快速移动至起始端而不处理任何请求
-
C-LOOK
- (在C-SCAN基础上)如果在磁头移动方向上已经没有别的请求,就可以立即改变磁头移动方向
减小磁盘延迟时间的方法
-
寻找时间(寻道时间):启动磁臂、移动磁头所花的时间
-
延迟时间:将目标扇区转到磁头下面所花的时间
- 磁头读取一块内容后,需要一小段的时间处理,不能连续读取接下来的扇区
- 采用交替编号策略:将逻辑相邻的扇区在物理上间隔开
- 采用错位命名:把不同盘面同一物理位置错开命名
-
地址结构设计:柱面号在盘面号之前而不是之后,读取地址连续的磁盘块时,可以减少磁头移动消耗的时间(把同一盘面单个磁头移动 改为 激活不同盘面的不同磁头
磁盘的管理
-
磁盘初始化
- 低级格式化/物理分区:划分扇区。一个扇区通常分为头,尾,数据区域
- 磁盘分区(C、D盘)
- 逻辑格式化
-
引导块
- ROM不可修改,ROM中只存放很小的“自举装入程序”,完整的程序存放在磁盘上的启动块(引导块上)
- 启动/系统磁盘
-
坏块的管理
- 在FAT表上标明(坏块对操作系统不透明)
- 扇区备用:好的备用快替换坏块