操作系统
第一章计算机系统概述
1.1操作系统的基本概念
1.1.1操作系统的概念、功能
1,概念
操作系统(Operating System,os)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本系统软件。
2,功能和目标
1,系统资源的管理者
文件管理
存储器管理
处理机(CPU)管理
设备管理
2,向上层提供服务
- 给普通用户的
GUI:图形化用户接口(Graphical User lnterface)用户可以使用形象的图形界面进行操作,而不再需要记忆复杂的命令、参数。
命令接口
联机命令接口实例(Windows系统)联机命令接口=交互式命令接口
特点:用户说一句,系统跟着做一句
脱机命令接口=批处理命令接口,脱机命令接口实例(Windows系统)
特点:用户说一堆,系统跟着做一堆
- 给软件/程序员用的
程序接口:可以在程序中进行系统调用来使用程序接口。普通用户不能直接使用程序接口,只能通过程序代码间接使用。
3,对硬件机器的扩展
没有任何软件支持的计算机成为裸机。在裸机上安装的操作系统,可以提供资源管理功能和方便用户的服务功能,将裸机改造成功能更强、使用更方便的机器通常把覆盖了软件的机器成为扩充机器,又称之为虚拟机。
1.1.2操作系统的四个特征
并发和共享互为存在条件
没有并发和共享,就谈不上虚拟和异步,因此并发和共享是操作系统的两个最基本的特征
1,并发
并发:指两个或多个事件在间一时间间隔内发生。这些事件定观上是间时发生的,但微观上是交替发生的。
常考易混概念一一并行:指两个或多个事件在同一时刻同时发生。
操作系统的并发性指计算机系统中“同时”运行着多个程序,这些程序宏观上看是同时运行着的,而微观上看是交替运行的。
操作系统就是伴随着“多道程序技术”而出现的。因此,操作系统和程序并发是一起诞生的。
注意(重要考点):
单核CPU同一时刻只能执行一个程序,各个程序只能并发地执行
多核CPU同一时刻可以同时执行多个程序,多个程序可以并行地执行
2,共享
共享即资源共享,是指系统中的资源可供内存中多个并发执行的进程共同使用。
- 互斥共享方式:
系统中的某些资源,虽然可以提供给多个进程使用,但一个时间段只允许一个进程访问该资源
- 同时共享方式:
系统中的某些资源,允许一个时间段内由多个进程“同时”(宏观上同时,微观上交替)对它们进行访问。
所谓的“同时”往往是宏观上的,而在微观上,这些进程可能是交替地对该资源进行访问的(即分时共享)
并发性指计算机系统中同时存在着多个运行着的程序。
共享性是指系统中的资源可供内存中多个并发执行的进程共同使用。
并发性共享性互为存在条件
3,虚拟
虚拟是指把一个物理上的实体变为若干个逻辑上的对应物。物理实体(前者)是实际存在的,而逻辑上对应物(后者)是用户感受到的。
分为空分复用技术(如虚拟存储器技术)和时分复用技术(如虚拟处理器)
4,异步
异步是指,在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。
1.2操作系统的发展与分类
1,手工操作阶段
主要缺点:用户独占全机、人机速度矛盾导致资源利用率极低
2,批处理阶段
单道批处理系统
引入脱机输入/输出技术(用外围机+磁带完成),并由监督程序负责控制作业的输入、输出
通过外围机把程序提前存到磁带里
- 主要优点:
缓解了一定程度的人机速度矛盾,资源利用率有所提升。
- 主要缺点:
内存中仅能有一道程序运行,只有该程序运行结束之后才能调入下一道程序。
CPU有大量的时间是在空闲等待I/O完成。资源利用率依然很低。
多道批处理系统
主要优点:多道程序并发执行,共享计算机资源。资源利用率大幅提升,CPU和其他资源更能保持“忙碌”状态,系统吞吐量增大。
主要缺点:用户响应时间长,没有人机交互功能(用户提交自己的作业之后就只能等待计算机处理完成,中间不能控制自已的作业执行。
eg:无法调试程序/无法在程序运行过程中输入一些参数)
3,分时操作系统
计算机以时间片为单位轮流为各个用户/作业服务,各个用户可通过终端与计算机进行交互。
- 主要优点:
用户请求可以被即时响应,解决了人机交互问题。允许多个用户同时使用一台计算机,并且用户对计算机的操作相互独立,感受不到别人的存在。
- 主要缺点:
不能优先处理一些紧急任务。操作系统对各个用户/作业都是完全公平的,循环地为每个用户/作业服务一个时间片,不区分任务的紧急性。
4,实时操作系统
- 主要优点:
能够优先响应一些紧急任务,某些紧急任务不需时间片排队。
在实时操作系统的控制下,计算机系统接收到外部信号后及时进行处理,并且要在严格的时限内处理完事件。实时操作系统的主要特点是及时性和可靠性。
- 分类:
硬实时操作系统:必须在绝对严格的规定时间内完成处理
软实时操作系统:能接受偶尔违反时间规定
5,网络操作系统
网络操作系统:是伴随着计算机网络的发展而诞生的,能把网络中各个计算机有机地结合起来,实现数据传送等功能,实现网络中各种资源的共享(如文件共享)和各台计算机之间的通信。(如:Windows NT 就是一种典型的网络操作系统,网站服务器就可以使用)
6,分布式操作系统
主要特点是分布性和并行性。系统中的各台计算机地位相同,任何工作都可以分布在这些计算机上,由它们并行、协同完成这个任务。
7,个人计算机系统
如Windows XP、MacOS,方便个人使用。
1.3操作系统运行环境
1.3.1操作系统的运行机制
1,程序运行原理
高级语言编写代码—>机器指令
程序运行的过程就是CPU执行指令的过程
2,两类程序
- 内核程序
微软、苹果有一帮人负责实现操作系统,他们写的是“内核程序”由很多内核程序组成了“操作系统内核”,或简称“内核(Kernel)内核是操作系统最重要最核心的部分,也是最接近硬件的部分
- 应用程序
普通程序员写的程序
3,两类指令
- 特权指令
操作系统内核作为“管理者”,有时会让CPU执行一些“特权指令”,如:内存清零指令。这些指令影响重大,只允许“管理者”——即操作系统内核来使用
- 非特权指令
应用程序只能使用“非特权指令”,如:加法指令、减法指令等
4,两种处理器状态
- 内核态
处于内核态时,说明此时正在运行的是内核程序,此时可以执行特权指令
- 用户态
处于用户态时,说明此时正在运行的是应用程序,此时只能执行非特权指令
拓展:CPU中有一个寄存器叫程序状态字寄存器(PSW),其中有个二进制位,1表示
“内核态”,0表示“用户态”
别名:内核态=核心态=管态:用户态=目态
5,内核
内核(Kernel)是操作系统最重要最核心的部分
由很多内核程序组成操作系统内核
6,如何改变处理器状态
内核态→用户态:执行一条特权指令–修改PSW的标志位为“用户态”,这个动作意味着操作系统将主动让出CPU使用权
用户态→内核态:由“中断”引发,硬件自动完成变态过程,触发中断信号意味着操作系统将强行夺回CPU的使用权
1.3.2中断和异常
1,中断的作用
“中断”是让操作系统内核夺回CPU使用权的唯一途径
如果没有“中断”机制,那么一旦应用程序上CPU运行,CPU就会一直运行这个应用程序。
2,中断的类型
1,内中断(也称异常,例外)
与当前执行的指令。中断信号来源于CPU内部。CPU在执行指令时会检查是否有异常发生
- 陷阱、陷入(trap)
由陷入指令引发,是应用程序故意引发的
- 故障(falut)
由错误条件引起的,可能被内核程序修复,内核程序修复故障后会把CPU使用权还给应用程序,让它维续执行下去。如:缺页故障。
- 终止(abort)
由致命错误引起,内核程序无法修复该错误,因此一般不再将CPU使用权还给引发终止的应用程序,而是直接终止该应用程序。如:整数除0、非法使用特权指令
2,外中断(也称“中断”,是狭义的中断)
与当前执行的指令,中断信号来源于CPU外部,每一条指令执行结束时,CPU都会例行检查是否有外中断信号
-
时钟中断
-
I/O中断请求
3,中断机制的基本原理
不同的中断信号,需要用不同的中断处理程序来处理。当CPU检测到中断信号后,会根据中断信号的类型去查询“中断向量表”,以此来找到相应的中断处理程序在内存中的存放位置。
1.3.3系统调用
1,什么是系统调用
“系统调用”是操作系统提供给应用程序(程序员/编程人员)使用的接口,可以理解为一种可供应用程序调用的特殊函数,应用程序可以通过系统调用来请求获得操作系统内核的服务。
2,系统调用与库函数的区别
- 普通应用程序
可直接进行系统调用,也可使用库函数。有的库函数涉及系统调用,有的不涉及用程序
- 编程语言
向上提供库函数。有时会将系统调用封装成库函数,以隐藏系统调用的一些细节,使程序员编程更加方便。
- 操作系统
向上提供系统调用,使得上层程序能请求内核的服务
- tips:
不涉及系统调用的库函数:如的“取绝对值”的函数
涉及系统调用的库函数:如“创建一个新文件”的函数
3,为什么系统调用是必须的
应用程序通过系统调用请求操作系统的服务。而系统中的各种共享资源都由操作系统内核统一掌管,因此凡是与共享资源有关的操作(如存储分配、I/O操作、文件管理等),都必须通过系统调用的方式向操作系统内核提出服务请求,由操作系统内核代为完成。这样可以保证系统的稳定性和安全性,防止用户进行非法操作。
4,什么功能要系统调用实现
凡是与共享资源有关的操作、会直接影响到其他进程的操作,就定需要操作系统介入,就需要通过系统调用来实现
1,设备管理
完成设备的请求/释放/启动等功能
2,文件管理
完成文件的读/写/创建/删除等功能
3,进程控制
完成进程的创建/撤销/阻塞/唤醒等功能
4,进程通信
完成进程之间的消息传递/信号传递等功能
5,内存管理
完成内存的分配/回收等功能
5,系统调用的过程
传递系统调用参数—>执行陷入指令(用户态)—> 执行相应的内请求核程序处理系统调用(核心态) —> 返回
应用程序
注意:
-
陷入指令是在用户态执行的,执行陷入指令之后立即引发一个内中断,使CPU进入内核态
-
发出系统调用请求是在用户态,而对系统调用的相应处理在核心态下进行
注意别名:
陷入指令=trap指令=访管指令
1.4操作系统的体系结构
内核是操作系统最基本、最核心的部分。
实现操作系统内核功能的那些程序就是内核程序。
1,大内核(又名:宏内核/单内核)
将操作系统的主要功能模块都作为系统内核,运行在核心态
优点:高性能
缺点:内核代码庞大,结构混乱,难以维护
典型的大内核/宏内核/单内核操作系统:Linux、UNIX
2,微内核
只把最基本的功能保留在内核
优点:内核功能少,结构清晰,方便维护
缺点:需要频繁地在核心态和用户态之间切换,性能低
典型的微内核操作系统: Windows NT
3,分层结构
1,特性思想
内核分多层,每层可单向调用更纸一层提供的接口
2,优点
1.使于调试和验证,自底向上逐居调试验证
2.易扩充和易维护,各层之间调用接口清晰固定
3,缺点
1.仅可调用相邻低层,难以合理定义各层的边界
2.效率低,不可跨层调用,系统调用执行时间长
4,模块化
1,特性思想
将内核划分为多个模块,各模块之间相互协作。
内核=主模块+可加载内核模块
主模块:只负责核心功能,如进程调度、内存管理
可加载内核模块:可以动态加载新模块到内核。而无需重新编译整个内核
2,优点
1.模块间逻辑清听易于维护,确定模块间接口后即可多模块同时开发
2.支持动态加载新的内核模块(如:安装设备动程序、安装新的文件系统模块到内核),增强OS适应性
3.任何模块都可以直接调用其他模块,无需采用消息传递进行通信,效率高
3,缺点
1模块同的接口定义来必合理、实用
2.模块间相互依就,更难调试和验证
5,外核
1,特性思想
内核负责进程调度,进程通信等功能,外核负责为用户进程分配未经抽象的硬件资源,且由外核负责保证资源使用安全
2,优点
1.外核可直接给用户进程分配“不虚拟,不抽象”的硬件资源,使用户进程可以更灵活的使用硬件资源
2.减少了虚拟硬件资源的“映射层”,提升效率
3,缺点
1.降低了系统的一致性
2.使系统变得更复杂
1.5操作系统的引导
操作系统引导(boot)——开机的时候,怎么让操作系统运行起来?
1,磁盘里有哪些和操作系统引导相关的数据
1,主引导记录(MBR):
包含磁盘引导程序和分区表
分区表:说明了每个盘,每个分区分别占多大空间,以及每个分区的地址范围
2,C盘:是这个磁盘的活动分区,安装了操作系统
引导记录PBR,负责找到启动管理器
根目录,可见的文件夹目录等等。
3,主存由RAM和ROM组成
RAM掉电易失
ROM(存储的是BIOS)
包含:ROM引导程序,即自举程序
2,操作系统引导具体过程
①CPU从一个特定主存地址开始,取指令,执行ROM中的引导程序(先进行硬件自检,再开机)
②将磁盘的第一块—一主引导记录(MBR)读入内存,执行磁盘引导程序,扫描分区表
③从活动分区(又称主分区,即安装了操作系统的分区)读入分区引导记录(PBR),执行其中的程序
④从根目录下找到完整的操作系统初始化程序(即启动管理器)并执行,完成“开机”的一系列动作
1.6虚拟机
1,传统计算机
一台物理机器上只能运行一个操作系统
2,虚拟机
虚拟机:使用虚拟化技术,将一台物理机器虚拟化为多台虚拟机器(Virtual Machine,VM),每个虚拟机器都可以独立运行一个操作系统
同义术语:虚拟机管理程序/虚拟机监控程序/Virtual Machine Monitor/Hypervisor
3,两类VMM
第一类VMM | 第二类VMM | |
---|---|---|
对物理资源的控制权 | 直接运行在硬件之上,能直接控制和分配物理资源 | 运行在Host OS之上,依赖于Host OS为其分配物理资源 |
资源分配方式 | 在安装Guest OS时,VMM要在原本的硬盘上自行分配存储空间,类似于“外核”的分配方式,分配未经抽象的物理硬件 | GuestOS 拥有自己的虚拟磁盘,该盘实际上是Host OS文件系统中的一个大文件。GuestOS分配到的内存是虚拟内存 |
性能 | 性能更好 | 性能更差,需要HostOS作为“中介” |
可支持的虚拟机的数量 | 更多,不需要和HostOS竞争资源,相同的硬件资源可以支持更多的虚拟机 | 更少,Host OS本身需要使用物理资源,HostOS上运行的其他进程也需要物理资源 |
虚拟机的可迁移性 | 更差 | 更好,只需导出虚拟机镜像文件即可迁移到另一台HostOS上,商业化应用更广泛 |
运行模式 | 第一类VMM运行在最高特权级(Ring 0),可以执行最高特权的指令。 | 第二类VMM部分运行在用户态、部分运行在内核态。GuestOS发出的系统调用会被VMM截获,并转化为 VMM对HostOS的系统调用 |
第二章进程与线程
2.1进程与线程
2.1.1进程的概念,组成,特征
1,进程的概念
程序:是静态的,就是个存放在磁盘里的可执行文件,如:QQ.exe。
进程:是动态的,是程序的一次执行过程,如:可同时启动多次QQ程序。
同一个程序多次执行会对应多个进程
2,进程的组成
一个进程实体(进程映像)由PCB、程序段、数据段组成。
PCB是给操作系统用的。
程序段、数据段是给进程自己用的。
进程是动态的,进程实体(进程映像)是静态的。
进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
所以这里更确切的说是进程实体的组成。
1,PCB进程控制块
操作系统需要对各个并发运行的进程进行管理,但凡操作系统对进程管理时所需要的信息,都会被放在PCB中,是给操作系统用的
- 进程描述信息
进程标识符PID
当进程被创建时,操作系统会为该进程分配一个唯一的, 不重复的“身份证号”–PID (Process ID,进程D)
用户标识符UID
- 进程控制和管理信息
CPU、磁盘、网络流量使用情况统计.…
进程当前状态:就绪态/阻塞态/运行态…
- 资源分配清单
正在使用哪些文件
正在使用哪些内存区域
正在使用哪些I/O设备
- 处理机相关信息
如PSW、PC等等各种寄存器的值(用于实现进程切换)
2,程序段
程序的代码(指令序列)
3,数据段
运行过程中产生的各种数据(如:程序中定义的变量)
3,进程的特征
1,动态性
进程是程序的一次执行过程,是动态产生、变化和消亡的,是进程的最基本特征
2,并发性
内存中有多个进程实体,各进程可并发执行
3,独立性
进程是能独立运行,独立获得资源,独立接受调度的基本单位
4,异步性
各进程按各自独立的,不可预知的速度向前推进,操作系统要提供进程同步机制来解决异步问题
5,结构性
每个进程都会配置一个PCB,结构上看,进程由程序段,数据段,PCB组成
2.1.2进程的状态与转换
1,进程的状态
1,创建状态
进程正在被创建时,它的状态是“创建态”,在这个阶段操作系统会为进程分配资源、初始化PCB
2,就绪状态
当进程创建完成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行
3,运行状态
如果一个进程此时在CPU上运行,那么这个进程处于“运行态
CPU会执行该进程对应的程序(执行指令序列)
4,阻塞态
在进程运行的过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的应)。
在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态”
5,终止状态
一个进程可以执行exit系统调用,请求操作系统终止该进程。
此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。
当终止进程的工作完成之后,这个进程就彻底消失了。
TIPS
不能由阻塞态直接转换为运行态,也不能由就绪态直接转换为阻塞态(因为进入阻塞态是进程主动请求的,必然需要进程在运行时才能发出这种请求)
2,进程间的状态转换
单CPU情况下,同一时刻只会有一个进程处于运行态,多核CPU情况下,可能有多个进程处于运行态
1,就绪态转运行态
进程被调度
2,运行态转就绪态
进程的时间片被用完或者CPU被其它高优先级的进程抢占
3,运行态转阻塞态
等待系统资源分配或者等待某事件的发生(进程的主动行为)
4,阻塞态转就绪态
等待的资源分配到位或者等待的事件发生了(进程的被动行为)
5,创建态转就绪态
系统完成创建进程相关的工作
6,运行态转终止态
进程运行结束或者运行过程中遇到不可修复的错误
3,进程的组织方式
- 链式方式
按照进程状态将PCB分为多个队列
操作系统持有指向各个队列的指针
- 索引方式
根据进程状态的不同,建立几张索引表
操作系统持有指向各个索引表的指针
2.1.3进程控制
1,基本概念
1,什么是进程控制
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现
进程状转换等功能。进程控制就是要实现进程状态的转换
2,如何实现进程控制
进程控制用原语实现,是一种特殊的程序,它的执行具有原子性。也就是说,进程控制这段程序的运行必须一气呵成,不可中断
2,相关原语
原语的执行具有原子性,即执行过程只能一气呵成,期间不允许被中断。
可以用“关中断指令”和“开中断指令”这两个特权指令实现原子性
1,进程的创建
操作系统创建一个进程时使用的原语
- 创建原语
申请空白PCB
为新进程分配所需资源
初始化PCB
将PCB插入就绪队列(创建态—>就绪态)
- 引起进程创建的事件
用户登录:分时系统中,用户登录成功,系统会建立为其建立一个新的进程
作业(程序)调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求
应用请求:由用户进程主动请求创建一个子进程
2,进程的终止
就绪态/阻素态/运行态→终止态→无
- 撤销原语
从PCB集合中找到终止进程的PCB
若进程正在运行,立即剥夺CPU,将CPU分配给其他进程
终止其所有子进程(进程间的关系是树形结构)
将该进程拥有的所有资源归还给父进程或操作系统
删除PCB
- 引起进程终止的事件
正常结束:进程自己请求终止(exit系统调用)
异常结束:整数除以0、非法使用特权指令等,然后被操作系统强行杀掉
外界干预:Ctrl+Alt+delete,用户选择杀掉进程
3,进程的阻塞
阻塞原语唤醒原语必须成对使用
- 阻塞原语(运行态→阻塞态)
找到要阻塞的进程对应的PCB
保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行
将PCB插入相应事件的等待队列
- 引起阻塞的事件
需要等待系统分配某种资源
需要等待相互合作的其他进程完成工作
4,进程的唤醒
阻塞原语唤醒原语必须成对使用
- 唤醒原语(阻塞态→就绪态)
在事件等待队列中找到PCB
将PCB从等待队列移除,设置进程为就绪态
将PCB插入就绪队列,等待被调度
- 引起进程唤醒事件
等待的事件发生。因何事阻塞,就应由何事唤醒
5,进程的切换
- 切换原语(运行态→就绪态,就绪态→就绪态)
将运行环境信息(进程上下文)存入PCB
PCB移入相应队列
选择另一个进程执行,并更新其PCB
根据PCB恢复新进程所需的运行环境
- 引起进程切换的事件
当前进程时间片到
有更高优先级的进程到达
当前进程主动阻塞
当前进程终止
2.1.4进程间通信
进程间通信(Inter-Process Communication,IPC)是指两个进程之间产生数据交互。
进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立。
为了保证安全,一个进程不能直接访问另一个进程的地址空间。
1,共享存储
设置一个共享内存区域,并映射到进程的虚拟地址空间
要互斥地访间共享空间(由通信进程自己负责实现互斥)
为避免出错,各个进程对共享空间的访问应该是互斥的。
各个进程可使用操作系统内核提供的同步互斥工具(如P、V操作)
- 基于数据结构的共享(低级)
比如共享空间里只能放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式
- 基于存储区的共享(高级)
操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。
2,消息传递
进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。
- 直接通信方式
消息发送进程要指明接收进程的ID,消息直接挂到接收进程的消息队列里
- 间接通信方式
消息先发到中间体(信箱),通过“信箱”间接地通信。因此又称“信箱通信方式”
3,管道通信
“管道”是一个特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区,具有先进先出的特性是数据流的形式。
1.管道只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道。
2.各进程要互斥地访问管道(由操作系统实现)
3.当管道写满时,写进程将阻塞,直到读进程将管道中的数据取走,即可唤醒写进程。
4.当管道读空时,读进程将阻塞,直到写进程往管道中写入数据,即可唤醒读进程。
5.管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:
①一个管道允许多个写进程,一个读进程(2014年408真题高教社官方答案);
②允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux的方案)。
2.1.5 线程的概念
1,什么是线程。为什么要引入线程
有的进程可能需要“同时”做很多事,而传统的进程只能串行地执行一系列程序。为此,引入了“线程”,来增加并发度。“
引入线程后,线程成为了程序执行流的最小单位。
线程是一个基本的CPU执行单元,也是程序执行流的最小单位。引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如QQ视频、文字聊天、传文件)
引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。
线程则作为处理机的分配单元。
2,引入线程机制后,有什么变化
1,资源分配、调度
传统进程机制中,进程是资源分配、调度的基本单位
引入线程后,进程是资源分配的基本单位,线程是调度的基本单位
2,并发性
传统进程机制中,只能进程间并发
引入线程后,各线程间也能并发,提升了并发度
3,系统开销
传统的进程间并发,需要切换进程的运行环境,系统开销很大
线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小
引入线程后,并发所带来的系统开销减小
3,线程的属性
线程是处理机调度的单位
多CPU计算机中,各个线程可占用不同的CPU
每个线程都有一个线程ID、线程控制块(TCB)
线程也有就绪、阻塞、运行三种基本状态
线程几乎不拥有系统资源
同一进程的不同线程间共享进程的资源
由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预
同一进程中的线程切换,不会引起进程切换
不同进程中的线程切换,会引起进程切换
切换同进程内的线程,系统开销很小
切换进程,系统开销较大
2.1.6线程的实现方式和多线程模型
1,实现方式
- 用户级线程
从用户视角能看到的线程,由线程库实现
1.用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)
2.用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。
3.在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程”
4.优缺点
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行。
- 内核级线程
从操作系统视角看到的线程,由操作系统实现
内核级线程才是处理机分配的单位
1.内核级线程的管理工作由操作系统内核完成。
2.线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。
3.操作系统会为每个内核级线程建立相应的TCB(Thread Control Block,线程控制块),通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程”
4.优缺点
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
- 组合方式
用户级线程和内核级线程的结合,由此引入了下面几种多线程模型
2,多线程模型
- 一对一模型
一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
- 多对一模型
多对一模型:多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行
重点:
操作系统只“看得见”内核级线程,因此只有内核级线程才是处理机分配的单位。
- 多对多模型
多对多模型:线程(n>=m)。每个用户进程对应m个内核级线程。
克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。
可以这么理解:
用户级线程是“代码逻辑”的载体,内核级线程是“运行机会”的载体
内核级线程才是处理机分配的单位。
2.1.7线程的状态与转换(与进程类似)
1,状态与转换
就绪态,运行态,阻塞态
2,组织与控制
线程控制块(TCB)
线程表(J将多个TCB组织起来)
2.2处理机调度
2.2.1调度的概念,层次
1,基本概念
当有一堆任务要处理,但由于资源有限,这些事情没法同时处理。这就需要确定某种规则来决定处理这些任务的顺序,这就是“调度”研究的问题。
2,三个层次
1,高级调度(作业调度)
按一定的原则从外存的作业后备队列中挑选一个作业调入内存,并创建进程。每个作业只调入一次,调出一次。作业调入时会建立PCB,调出时才撤销PCB。
2,中级调度(内存调度)
中级调度(内存调度)——按照某种策略决定将哪个处于挂起状态的进程重新调入内存。一个进程可能会被多次调出、调入内存,因此中级调度发生的频率要比高级调度更高。
内存不够时,可将某些进程的数据调出外存。等内存空闲或者进程需要运行时再重新调入内存。
暂时调到外存等待的进程状态为挂起状态。被挂起的进程PCB会被组织成挂起队列
3,低级调度(进程调度)
按照某种策略从就绪队列中选取一个进程,将处理机分配给它。
进程调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度。
进程调度的频率很高,一几十毫秒一次。
3,三层调度的联系、对比
要做什么 | 调度发生在 | 发生频率 | 对进程状态的影响 | |
---|---|---|---|---|
高级调度(作业调度) | 按照某种规则,从后备队列中选择合适的作业将其调入内存,并为其创建进程 | 外存→内存(是面向作业的) | 最低 | 无→创建态→就绪态 |
中级调度(内存调度) | 按照某种规则,从挂起队列中选择合适的进程将其数据调回内存 | 外存→内存(是面向进程的) | 中等 | 挂起态→就绪态(阻塞挂起→阻塞态) |
低级调度(进程调度) | 按照某种规则,从就绪队列中选择一个进程为其分配处理机 | 内存→CPU | 最高 | 就绪态→运行态 |
4,进程的七状态模型
暂时调到外存等待的进程状态为挂起状态(挂起态,suspend)挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态
注意“挂起”和“阻塞”的区别,两种状态都是暂时不能获得CPU的服务,但挂起态是将进程映像调到外存去了,而阻塞态下进程映像还在内存中。有的操作系统会把就绪挂起、阻塞挂起分为两个挂起队列,甚至会根据阻塞原因不同再把阻塞挂起进程进一步细分为多个队列。
2.2.2进程调度的时机、切换与过程、方式
进程调度(低级调度),就是按照某种算法从就绪队列中选择一个进程为其分配处理机。
1,时机
1,什么时候需要进程调度
- 当前运行的进程主动放弃处理机
进程正常终止
运行过程中发生异常而终止
进程主动请求阻塞(如等待I/O)
- 当前运行的进程被动放弃处理机
分给进程的时间片用完
有更紧急的事需要处理(如l/0中断)
有更高优先级的进程进入就绪队列
2,什么时候不能进行进程调度
1.在处理中断的过程中。中断处理过程复杂,与硬件密切相关,很难做到在中断处理过程中进行进程切换。
2.进程在操作系统内核程序临界区中。
3.在原子操作过程中(原语)。原子操作不可中断,要一气呵成(如之前讲过的修改PCB中进程状态标志,并把PCB放到相应队列)
2,切换与过程
1,调度切换的区别
狭义的进程调度指的是从就绪队列中选中一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程,也可能是另一个讲程,后一种情况就需要进程切换)
进程切换是指一个进程让出处理机,由另一个进程占用处理机的过程。
广义的进程调度包含了选择一个进程和进程切换两个步骤。
2,切换过程
进程切换的过程主要完成了:
1.对原来运行进程各种数据的保存
2.对新的进程各种数据的恢复(如:程序计数器、程序状态字、各种数据寄存器等处理机现场信息,这些信息一般保存在进程控制块)
3,结论
进程切换是有代价的,因此如果过于频繁的进行进程调度、切换,必然会使整个系统的效率降低,使系统大部分时间都花在了进程切换上,而真正用于执行进程的时间减少。
3,方式
1,非剥夺调度方式(非抢占式)
只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止或主动要求进入阻塞态。
实现简单,系统开销小但是无法及时处理紧急任务,适合于早期的批处理系统
2,剥夺调度方式(抢占式)
当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要紧迫的那个进程。
可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能(通过时钟中断)。适合于分时操作系统、实时操作系统
2.2.3调度器和闲逛进程
1,调度器(调度程序)
管理进程状态切换的程序
·非抢占式调度策略,只有运行进程阻塞或退出才触发调度程序工作
·抢占式调度策略,每个时钟中断或k个时钟中断会触发调度程序工作
支持内核级线程的操作系统,调度程序的处理对象是内核线程
不支持内核级线程的操作系统,调度程序的处理对象是进程
2,闲逛进程
调度程序永远的备胎,没有其他就绪进程时,运行闲逛进程(idle)
闲逛进程的特性:
·优先级最低
·可以是0地址指令,占一个完整的指令周期(指令周期末尾例行检查中断)
·能耗低
2.2.4调度算法的评价指标
1,CPU利用率
CPU利用率:指CPU“忙碌”的时间占总时间的比例。
利用率=忙碌的时间/总时间
2,系统吞吐量
单位时间内完成作业的数量
系统吞吐量=(总共完成了多少道作业)/(总共花了多少时间)
3,周转时间
周转时间,是指从作业被提交给系统开始,到作业完成为止的这段时间间隔。
它包括四个部分:
作业在外存后备队列上等待作业调度(高级调度)的时间、
进程在就绪队列上等待进程调度(低级调度)的时间、
进程在CPU上执行的时间、
进程等待1/0操作完成的时间。
后三项在一个作业的整个处理过程中,可能发生多次。
(作业)周转时间=作业完成时间-作业提交时间
平均周转时间=(作业周转时间之和)/(作业数)
带权周转时间=(作业周转时间/(作业实际运行的时间)
=(作业完成时间-作业提交时间)/(作业实际运行的时间)
平均带权周转时间=(各作业带权周转时间之和)/(作业数)
4,等等时间
等待时间,指进程/作业处于等待处理机状态时间之和,等待时间越长,用户满意度越低。
对于进程来说,等待时间就是指进程建立后等待被服务的时间之和,在等待I/0完成的期间其实进程也是在被服务的,所以不计入等待时间。
对于作业来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间。
一个作业总共需要被CPU服务多久,被I/O设备服务多久一般是确定不变的,因此调度算法其实只会影响作业/进程的等待时间。当然,与前面指标类似,也有“平均等待时间”来评价整体性能。
5,响应时间
对于计算机用户来说,会希望自己的提交的请求(比如通过键盘输入了一个调试命令)尽早地开始被系统服务、回应。
响应时间,指从用户提交请求到首次产生响应所用的时间。
2.2.5调度算法(1)
注:下面这几种算法主要关心对用户的公平性、平均周转时间、平均等待时间等评价系统整体性能的指标,但是不关心“响应时间”,也并不区分任务的紧急程度,因此对于用户来说,交互性很糟糕。因此这三种算法一般适合用于早期的批处理系统,当然,FCFS算法也常结合其他的算法使用,在现在也扮演着很重要的角色
1,先来先服务(FCFS,FirstCome First Serve)
1,算法思想
主要从“公平”的角度考虑(类似于我们生活中排队买东西的例子)
2,算法规则
按照作业/进程到达的先后顺序进行服务
3,用于作业/进程调度
用于作业调度时,考虑的是哪个作业先到达后备队列;
用于进程调度时,考虑的是哪个进程先到达就绪队列
4,是否可抢占
非抢占式的算法
5,优缺点
优点:公平、算法实现简单
缺点:排在长作业(进程)后面的短作业需要等待很长时间,带权周转时间很大,对短作业来说用户体验不好。
即,FCFS算法对长作业有利,对短作业不利(Eg:排队买奶茶…)
6,是否会导致饥饿(某进程/作业长期得不到服务)
不会
2,短作业优先(SJF,ShortestJob First)
1,算法思想
追求最少的平均等待时间,最少的平均周转时间、最少的平均平均带权周转时间
2,算法规则
最短的作业/进程优先得到服务(所谓“最短”,是指要求服务时间最短)
3,用于作业/进程调度
即可用于作业调度,也可用于进程调度。用于进程调度时称为“短进程优先(SPE,Shortest Process First)算法”
4,是否可抢占
SJF和SPF是非抢占式的算法。但是也有抢占式的版本——最短剩余时间优先算法(SRTN,Shortest Remaining Time Next)
5,优缺点
优点:“最短的”平均等待时间、平均周转时间
缺点:不公平。对短作业有利,对长作业不利。可能产生饥饿现象。另外,作业/进程的运行时间是由用户提供的,并不一定真实,不一定能做到真正的短作业优先
6,是否会导致饥饿
会。如果源源不断地有短作业/进程到来,可能使长作业/进程长时间得不到服务,产生“饥饿”现象。如果一直得不到服务,则称为“饿死”
注意几个小细节:
1.如果题目中未特别说明,所提到的“短作业/进程优先算法”默认是非抢占式的
2.很多书上都会说“SJF调度算法的平均等待时间、平均周转时间最少”严格来说,这个表述是错误的,不严谨的。之前的例子表明,最短剩余时间优先算法得到的平均等待时间、平均周转时间还要更少应该加上一个条件“在所有进程同时可运行时,采用SJF调度算法的平均等待时间、平均周转时间最少”;或者说“在所有进程都几乎同时到达时,采用SJF调度算法的平均等待时间、平均周转时间最少”;如果不加上述前提条件,则应该说“抢占式的短作业/进程优先调度算法(最短剩余时间优先,SRNT算法)的平均等待时间、平均周转时间最少”
3.虽然严格来说,SJF的平均等待时间、平均周转时间并不一定最少,但相比于其他算法(如FCFS),SJF依然可以获得较少的平均等待时间、平均周转时间
4.如果选择题中遇到“SJF算法的平均等待时间、平均周转时间最少”的选项,那最好判断其他选项是不是有很明显的错误,如果没有更合适的选项,那也应该选择该选项
3,高响应比优先(HRRN,Highest Response Ratio Next)
1,算法思想
要综合考虑作业/进程的等待时间和要求服务的时间
2,算法规则
在每次调度时先计算各个作业/进程的响应比,选择响应比最高的作业/进程为其服务
响应比=(等待时间+要求服务时间)/(要求服务时间)
3,用于作业/进程调度
即可用于作业调度,也可用于进程调度
4,是否可抢占
非抢占式的算法。因此只有当前运行的作业/进程主动放弃处理机时,才需要调度,才需要计算响应比
5,优缺点
综合考虑了等待时间和运行时间(要求服务时间)等待时间相同时,要求服务时间短的优先(SJF的优点)要求服务时间相同时,等待时间长的优先(FCFS的优点)对于长作业来说,随着等待时间越来越久,其响应比也会越来越大,从而避免了长作业饥饿的问题
6,是否会导致饥饿
不会
2.2.6调度算法(2)
比起早期的批处理操作系统来说,由于计算机造价大幅降低,因此之后出现的交互式操作系统(包括分时操作系统、实时操作系统等)更注重系统的响应时间、公平性、平衡性等指标。而这几种算法恰好也能较好地满足交互式系统的需求。因此下面这三种算法适合用于交互式系统。(比如UNIX使用的就是多级反馈队列调度算法)
1,时间片轮转(RR,Round-Robin)
1,算法思想
公平地、轮流地为各个进程服务,让每个进程在一定时间间隔内都可以得到响应
2,算法规则
按照各进程到达就绪队列的顺序,轮流让各个进程执行一个时间片(如100ms)。若进程未在一个时间片内执行完,则剥夺处理机,将进程重新放到就绪队列队尾重新排队。
3,用于作业/进程调度
用于进程调度(只有作业放入内存建立了相应的进程后,才能被分配处理机时间片)
4,是否可抢占
若进程未能在时间片内运行完,将被强行剥夺处理机使用权,因此时间片轮转调度算法属于抢占式的算法。由时钟装置发出时钟中断来通知CPU时间片已到
5,优点和缺点
优点:公平;响应快,适用于分时操作系统;
缺点:由于高频率的进程切换,因此有一定开销;不区分任务的紧急程度。
6,是否会导致饥饿
不会
7,补充
如果时间片太大,使得每个进程都可以在一个时间片内就完成,则时间片轮转调度算法就会退化为先来先服务算法,并且会增大进程的响应时间,因此时间片不能太大
另一方面,进程调度、切换是有时间代价的,如果时间片太小,会导致进程切换过于频繁,系统会画大量时间来处理进程切换,从而导致实际用于进程执行的世界比例减少,可见时间片也不能太小。
一般来说,设计时间片时要让切换进程的开销占比不超过1%
2,优先级调度算法
1,算法思想
随着计算机的发展,特别是实时操作系统的出现,越来越多的应用场景需要根据任务的紧急程度来决定处理顺序
2,算法规则
调度时选择优先级最高的作业/进程
3,用于作业/进程调度
既可用于作业调度,也可用于进程调度。甚至,还会用于在之后会学习的l/0调度中
4,是否可抢占
抢占式、非抢占式都有。做题时的区别在于:非抢占式只需在进程主动放弃处理机时进行调度即可,而抢占式还需在就绪队列变化时,检查是否会发生抢占。
5,优点和缺点
优点:用优先级区分紧急程度、重要程度,适用于实时操作系统。可灵活地调整对各种作业/进程的偏好程度。
缺点:若源源不断地有高优先级进程到来,则可能导致饥饿
6,是否会导致饥饿
会
7,补充
就绪队列未必只有一个,可以按照不同优先级来组织。另外,也可以把优先级高的进程排在更靠近队头的位置根据优先级是否可以动态改变,可将优先级分为静态优先级和动态优先级两种。
静态优先级:创建进程时确定,之后一直不变。
动态优先级:创建进程时有一个初始值,之后会根据情况动态地调整优先级。
通常:
系统进程优先级高于用户进程
前台进程优先级高于后台进程
操作系统更偏好I/O型进程(或称I/O繁忙型进程)
注:与I/O型进程相对的是计算型进程(或称CPU繁忙型进程)
3,多级反馈队列调度算法
1,算法思想
对其他五种调度算法的折中权衡
2,算法规则
1.设置多级就绪队列,各级队列优先级从高到低,时间片从小到大
2.新进程到达时先进入第1级队列,按FCFS原则排队等待被分配时间片,若用完时间片进程还未结束,则进程进入下一级队列队尾。如果此时已经是在最下级的队列,则重新放回该队列队尾
3.只有第k级队列为空时,才会为k+1级队头的进程分配时间片
3,用于作业/进程调度
用于进程调度
4,是否可抢占
抢占式的算法。在k级队列的进程运行过程中,若更上级的队列(1~k-1级)中进入了一个新进程,则由于新进程处于优先级更高的队列中,因此新进程会抢占处理机,原来运行的进程放回k级队列队尾。
5,优点和缺点
对各类型进程相对公平(FCFS的优点);
每个新到达的进程都可以很快就得到响应(RR的优点);
短进程只用较少的时间就可完成(SPF的优点);
不必实现估计进程的运行时间(避免用户作假);
可灵活地调整对各类进程的偏好程度,比如CPU密集型进程、I/0密集型进程(拓展:可以将因1/0而阻塞的进程重新放回原队列,这样1/0型进程就可以保持较高优先级)
6,是否会导致饥饿
会
2.2.7多级队列调度算法
系统中按进程类型设置多个队列,进程创建成功后插入某个队列
队列之间可采取固定优先级,或时间片划分
固定优先级:高优先级空时低优先级进程才能被调度
时间片划分:如三个队列分配时间50%、40%、10%
各队列可采用不同的调度策略,如:
系统进程队列采用优先级调度
交互式队列采用RR
批处理队列采用FCFS
2.3同步与互斥
2.3.1进程同步,互斥的基本概念
1,什么是进程同步
并发性带来了异步性,有时需要进过进程同步解决这种异步问题。
异步性是指,各并发执行的进程以各自独立的。不可预知的速度向前推进。
有的进程之间需要相互配合地完成工作,各进程的工作推进需要通情一定的先后项序。
所以操作系统提供“进程同步”的机制来解决异步问题。
进程同步也称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要再某些位置上协调它们的工作次序而产生的制约关系,进程间的直接制约关系就是源于它们间的相互合作。
2,什么是进程互斥
一个时间段内只充许一个进程使用的资源称为临界资源。
对临界资源的访问,必须互斥地进行。
互斥,亦称间接制约的关系,进程互斥指当一个进程访间某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后。另一个进程才能去访问临界资证。
1,四个部分
对临界资源的互斥访间,可以在逻辑上分为如下四个部分:
1,进入区
负责检查是否可进入临界区,若可进入,则应设置正在访问临界资源的标志(可理解为“上锁”),以阻止其他进程同时进入临界区
2,临界区
访问临界资源的那段代码
3,退出区
负责解除正在访问临界资源的标志(可理解为“解锁”)
4,剩余区
其余代码部分
2,需要遵循的原则
为了实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则:
1.空闲让进
临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
2.忙则等待
当已有进程进入临界区时,其他试图进入临界区的进程必须等待;
3.有限等待
对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿)
4.让权等待
当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。
2.3.2进程互斥的软件实现方法
1,单标志法
算法思想:
两个进程在游问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予。
在进入区只做“检查”,不“上锁”
在退出区把临界区的使用权转交给另一个进程(相当于在退出区既给另一进程“解锁”,又给自己“上锁”)
主要问题:不遵循“空闲让进“原则
2,双标志先检查
算法思想:
设置一个布尔型数组fagll,数组中各个元素用来标记各进程想进入临界区的意愿,比如
“flag[O]=ture”意味着0号进程PO现在想要进入临界区。每个进程在进入临界区之前先检查当前有
没有别的进程想进入临界区,如果没有,则把自身对应的标志ftag设为true, 之后开始访问临界区。
双标志先检查法的主要问题是:违反“忙则等待”原则。
原因在于,进入区的“检查”和“上锁”两个处理不是一气呵成的。“检查”后,“上锁”前可能发生进程切换。
3,双标志后检查
在进入区先“加锁“后“检查”,退出区“解锁”
主要问题:
因此,双标志后检查法虽然解决了“忙则等待”的问题,但是又违背了“空闲让进”和“有限等待”
原则,会因各进程都长期无法访问临界资源而产生“饥饿”现象。
两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区。
4,Peterson算法
算法思想:
结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试“孔融让梨”(谦让)。做一个有礼貌的进程。
进入区:
1.主动争取;
2.主动谦让
3.检查对方是否也想使用,且最后一次是不是自己说了“客气话”
主要问题:不遵循“让权等待“原则,会发生“忙等”
2.3.3进程互斥的硬件实现方法
1,中断屏蔽方法
利用“开/关中断指令”实现(与原语的实现思想相同,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个同时访问临界区的情况)
优点:简单高效
缺点:不适用于多处理机:只适用于操作系统内核进程,不适用于用户进程(因为开/关中断指令只能运行在内核态,这组指令如果能让用户随意使用会很危险)
2,TestAndSet(TS指令/TSL指令)
TSL指令是用硬件实现的,执行的过程不允许被中断,只能一气呵成。以下是用C语言描述的逻辑
相比软件实现方法,TSL指令把“上锁”和“检查”操作用硬件的方式变成了一气呵成的原子操作。
优点:实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞:适用于多处理机环境
缺点:不满足“让权等待”原则,暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致“忙等”。
3,Swap指令(XCHG指令)
逻辑上来看Swap和TSL并无太大区别,都是先记录下此时临界区是否已经被上锁(记录在old变量上),再将上锁标记lock设置为true,最后检查old,如果old为false则说明之前没有别的进程对临界区上锁,则可跳出循环,进入临界区。
优点:实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞:适用于多处理机环境
缺点:不满足“让权等待”原则,暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从
而导致“忙等”。
2.3.4互斥锁
解决临界区最简单的工具就是互斥锁(mutexlock)。一个进程在进入临界区时应获得锁;在退出临界区时释放锁。函数acquire获得锁,而函数release释放锁。
每个互斥锁有一个布尔变量available,表示锁是否可用。如果锁是可用的,调用acqiure()会
成功,且锁不再可用。当一个进程试图获取不可用的锁时,会被阻塞,直到锁被释放。
acquire或release的执行必须是原子操作,因此互斥锁通常采用硬件机制来实现。
互斥锁的主要缺点是忙等待,当有一个进程在临界区中,任何其他进程在进入临界区时必须
连续循环调用acquire()。当多个进程共享同一CPU时,就浪费了CPU周期。因此,互斥锁通常
用于多处理器系统,一个线程可以在一个处理器上等待,不影响甚他线程的执行。
需要连续循环忙等的互斥锁,都可称为自旋锁(spin lock),如TSL指令、swap指令、单标志法
特性:
·需忙等,进程时间片用完才下处理机,违反“让权等待”
·优点:等待期间不用切换进程上下文,多处理器系统中,若上锁的时间短,则等待代价很低
·常用于多处理器系统,一个核忙等,其他核照常工作,并快速释放临界区
·不太适用于单处理机系统,忙等的过程中不可能解锁
2.3.5信号量机制
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。
信号量其实就是一个变量(可以是一个整数,也可以是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量,比如:系统中只有一台打印机,就可以设置一个初值为1的信号量。
原语是一种特殊的程序段,其执行只能一气呵成,不可被中断。原语是由关中断/开中断指令实现的。
一对原语:wait(S)原语和signal(S)原语,可以把原语理解为我们自己写的函数,函数名分别为wait和signal,括号里的信号量S其实就是函数调用时传入的一个参数。
wait、signal 原语常简称为p、V操作(来自荷兰语proberen和verhogen)。因此,做题的时候常把wait(S)、signal(S)两个操作分别写为P(S)、V(S)。
1,整型信号量
用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。
整型信号量与普通整型变量的区别:对信号量只能执行初始化、P、V三种操作
整型信号量存在的问题:不满足让权等待原则
2,记录型信号量
S.value表示某种资源数,S.L指向等待该资源的队列
P操作中,一定是先S.value–,之后可能需要执行 block原语
对信号量S的一次P操作意味着进程请求一个单位的该类资源,因此需要执行S.value–,表示资源数减1,当S.value<0时表示该类资源已分配完毕,因此进程应调用block原语进行自我阻塞(当前运行的进程从运行态→阻塞态),主动放弃处理机,并插入该类资源的等待队列(阻塞队列)S.L中。可见,该机制遵循了“让权等待”原则,不会出现“忙等”现象。
V操作中,一定是先S.value++,之后可能需要执行 wakeup 原语
对信号量S的一次v操作意味着进程释放一个单位的该类资源,因此需要执行S.value++,表示资源数加1。若加1后仍是S.value<=0,表示依然有进程在等待该类资源,因此应调用wakeup原语唤醒等待队列(进程的阻塞队列)中的第一个进程(被唤醒进程从阻塞态→就绪态)。
注意:要能够自己推断在什么条件下需要执行block或 wakeup
可以用记录型信号量实现系统资源的“申请“和“释放”
可以用记录型信号量实现进程互斥、进程同步
2.3.6用信号量机制实现进程互斥、同步、前驱关系
1,实现进程互斥
互斥问题,信号量初值为1
分析问题,确定临界区
设置互斥信号量,初值为1
临界区之前对信号量执行P操作
临界区之后对信号量执行V操作
2,实现进程同步
进程同步:要让各并发进程按要求有序地推进。
同步问题,信号量初值为0
分析问题,找出哪里需要实现“一前一后”的同步关系
设置同步信号量,初始值为0
在“前操作“之后执行V操作
在“后操作“之前执行P操作
(前VP后)
3,实现进程的前驱关系
前驱关系问题,本质上就是多级同步问题
分析问题,画出前驱图,把每一对前驱关系都看成一个同步问题
为每一对前驱关系设置同步信号量,初值为0
在每个“前操作”之后执行V操作
在每个“后操作“之前执行P操作
2.3.7管程
1,为什么要引入管程
解决信号量机制编程麻烦,易出错的问题
2,管程的组成
共享数据结构
对数据结构初始化的语句
一组用来访问数据结构的过程(函数)
管程有一个名字
3,管程的基本特征
-
1.局部于管程的数据只能被局部于管程的过程(函数)所访问;
-
2.一个进程只有通过调用管程内的过程(函数)才能进入管程访问共享数据;
-
3.每次仅允许一个进程在管程内执行某个内部过程。
2.3.8经典的同步互斥问题
生产者消费者
读写
吸烟者
哲学家问题
2.4死锁
2.4.1死锁的概念
1,什么是死锁
在并发环境下,各进程因竞争资源而造成的一种互相等待对方手里的资源,导致各进程都阻塞,都无法向前推进的现象,就是“死锁”。发生死锁后若无外力干涉,这些进程都将无法向前推进。
2,死锁,饥饿,死循环的区别
都是进程无法顺利向前推进的现象(故意设计的死循环除外)
死锁:至少是两个进程一起死锁,死锁进程处于阻塞态
饥饿:可以只有一个进程饥饿,饥饿进程可能阻塞也可能就绪
死循环:可能只有一个进程发生死循环,死循环的进程可上处理机
死锁和饥饿是操作系统要解决的问题,死循环是应用程序员要解决的
3,死锁产生的必要条件
产生死锁必须同时满足一下四个条件,只要其中任一条件不成立,死锁就不会发生。
互斥条件:
只有对必须互斥使用的资源的争抢才会导致死锁(如哲学家的筷子、打印机设备)。像内存、扬声器这样可以同时让多个进程使用的资源是不会导致死锁的(因为进程不用阻塞等待这种资源)。
不剥夺条件:
进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放。
请求和保持条件:
进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放。
循环等待条件:
存在一种进程资源的循环等待链,链中的每一个进程已获得的资源同时被下一个进程所请求。
4,什么时候会发生死锁
1.对系统资源的竞争
各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源(CPU)的竞争是不会引起死锁的。
2.进程推进顺序非法
请求和释放资源的顺序不当,也同样会导致死锁。例如,并发执行的进程P1、P2分别申请并占有了资源R1、R2,之后进程P1又紧接着申请资源R2,而进程P2又申请资源R1,两者会因为申请的资源被对方占有而阻塞,从而发生死锁。
3.信号量的使用不当也会造成死锁
如生产者-消费者问题中,如果实现互斥的P操作在实现同步的P操作之前,就有可能导致死锁。(可以把互斥信号量、同步信号量也看做是一种抽象的系统资源)
5,死锁的处理策略
1.预防死锁
破坏死锁产生的四个必要条件中的一个或几个。
2.避免死锁
用某种方法防止系统进入不安全状态,从而避免死锁(银行家算法)
3.死锁的检测和解除
允许死锁的发生,不过操作系统会负责检测出死锁的发生,然后采取某种措施解除死锁。
2.4.2预防死锁(不允许死锁发生的静态策略)
1,破坏互斥条件
把只能互斥使用的资源改造为允许共享使用,则系统不会进入死锁状态。比如:SPOOLing技术。
缺点:可行性不高,很多时候无法破坏互斥条件
2,破坏不剥夺条件
方法一
当某个进程请求新的资源得不到满足时,它必须立即释放保持的所有资源,待以后需要时再重新申请。也就是说,即使某些资源尚未使用完,也需要主动释放,从而破坏了不可剥夺条件。
方法二
当某个进程需要的资源被其他进程所占有的时候,可以由操作系统协助,将想要的资源强行剥夺。这种方式一般需要考虑各进程的优先级(比如:剥夺调度方式,就是将处理机资源强行剥夺给优先级更高的进程使用)
该策略的缺点:
1.实现起来比较复杂。
2.释放已获得的资源可能造成前一阶段工作的失效。因此这种方法一般只适用于易保存和恢复状态的资源,如CPU。
3.反复地申请和释放资源会增加系统开销,降低系统吞吐量
4.若采用方案一,意味着只要暂时得不到某个资源,前获得的那些资源就都需要放弃,以后再重新申请。如果一直发生这样的情况,就会导致进程饥饿。
3,破坏请求和保持条件
可以采用静态分配方法,即进程在运行前一次申请完它所需要的全部资源,在它的资源未满足前,不让它投入运行。一旦投入运行后,这些资源就一直归它所有,该进程就不会再请求别的任何资源
该策略实现起来简单,但也有明显的缺点:有些资源可能只需要用很短的时间,因此如果进程的整个运行期间都一直保持着所有资源,就会造成严重的资源浪费,资源利用率极低。另外,该策略也有可能导致某些进程饥饿。
4,破坏循环等待条件
可采用顺序资源分配法。首先给系统中的资源编号,规定每个进程必须按编号递增的顺序请求资源,同类资源(即编号相同的资源)一次申请完。
原理分析:一个进程只有已占有小编号的资源时,才有资格申请更大编号的资源。按此规则,已持有大编号资源的进程不可能逆向地回来申请小编号的资源,从而就不会产生循环等待的现象。
该策略的缺点:
1.不方便增加新的设备,因为可能需要重新分配所有的编号;
2.进程实际使用资源的顺序可能和编号递增顺序不一致,会导致资源浪费:
3.必须按规定次序申请资源,用户编程麻烦。
2.4.3避免死锁(不允许死锁发生的动态策略)
1,什么是安全序列
所谓安全序列,就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。
2,什么是系统的不安全状态,与死锁的联系
如果分配了资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利的执行下去。当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过我们在分配资源之前总是要考虑到最坏的情况。
3,如何避免进入不安全状态—银行家算法
因此可以在资源分配之前预先判断这次分配是否会导致系统进入不安全状态,以此决定是否答应资源分配请求。这也是“银行家算法”的核心思想。
核心思想:在进程提出资源申请时,先预判此次分配是否会导致系统进入不安全状态。如果会进入不安全状态,就暂时不答应这次请求,让该进程先阻塞等待。
2.4.4死锁的检测和解除(允许死锁发生)
1,如何检测
为了能对系统是否已发生了死锁进行检测,必须:
①用某种数据结构来保存资源的请求和分配信息;
②提供一种算法,利用上述信息来检测系统是否已进入死锁状态。
1,数据结构:资源分配图
- 两种节点
进程节点:对应一个进程
资源节点:对应一类资源,一类资源可能有多个
- 两种边
进程节点→资源节点:表示进程想申请几个资源(每条边代表一个)
资源节点→进程节点:表示已经为进程分配了几个资源(每条边代表一个)
2,死锁检测算法
依次消除与不阻塞进程相连的边,直到无边可消
注:所谓不阻塞进程是指其申请的资源数还足够的进程
死锁定理:若资源分配图是不可完全简化的,说明发生了死锁
2,如何解除
一旦检测出死锁的发生,就应该立即解除死锁。补充:并不是系统中所有的进程都是死锁状态,用死锁检测算法化简资源分配图后,还连着边的那些进程就是死锁进程
1.资源剥夺法
挂起(暂时放到外存上)某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但是应防止被挂起的进程长时间得不到资源而饥饿。
2.撤销进程法(或称终止进程法)
强制撤销部分、甚至全部死锁进程,并剥夺这些进程的资源。这种方式的优点是实现简单,但所付出的代价可能会很大。因为有些进程可能已经运行了很长时间,已经接近结束了,一旦被终止可谓功亏一篑,以后还得从头再来。
3.进程回退法
让一个或多个死锁进程回退到足以避免死锁的地步。这就要求系统要记录进程的历史信息,设置还原点。
第三章内存管理
3.1内存管理的概念
3.1.1内存的基础知识
1,什么是内存,有何作用
内存可存放数据。程序执行前需要先放到内存中才能被CPU处理——缓和CPU与硬盘之间的速度矛盾
如果计算机“按字节编址”,则每个存储单元大小为1字节,即1B,即8个二进制位
如果字长为16位的计算机“按字编址”,则每个存储单元大小为1个字;每个字的大小为16个二进制位
2,进程运行的基本原理
1,指令的工作原理
操作码+若干参数(可能包含地址参数)
2,逻辑地址(相对地址)VS物理地址(绝对地址)
- 逻辑地址
程序经过编译、链接后生成的指令中指明的是逻辑地址(相对地址),即:相对于进程的起始地址而言的地址
- 物理地址
绝对地址
3,从写程序到程序运行
- 编译
由源代码文件生成目标模块(高级语言“翻译“为机器语言)
- 链接
由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块
- 装入(装载)
由装入程序将装入模块装入内存运行
4,三种链接方式
- 静态链接:
在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开。
- 装入时动态链接:
将各目标模块装入内存时,边装入边链接的链接方式。
- 运行时动态链接:
在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
5,三种装入方式
- 绝对装入
在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
绝对装入只适用于单道程序环境。
- 可重定位装入
静态重定位:又称可重定位装入。编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当位置。装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。
静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。
- 动态运行时装入
动态重定位:又称动态运行时装入。编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有的地址依然是逻辑地址。这种方式需要一个重定位寄存器的支持。
3.1.2内存管理的概念
1,内存空间的分配与回收
2,内存空间的扩充(实现虚拟性)
3,地址转换
操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地址的转换
绝对装入:编译器负责地址转换(单道程序阶段,无操作系统)
可重定位装入:装入程序负责地址转换(早期多道批处理阶段)
动态运行时装入:运行时才进行地址转换(现代操作系统)
4,内存保护
操作系统需要提供内存保护功能。保证各进程在各自存储空间内运行,互不干扰
方法一
在CPU中设置一对上、下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
方法二
采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址。
3.1.3覆盖与交换(内存空间扩充的技术)
1,覆盖技术
覆盖技术的思想:将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存。内存中分为一个”固定区“和若干个”覆盖区“
1,一个固定区
需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)
2,若干覆盖区
不常用的段放在覆盖区”,需要用到时调入内存,用不到时调出内存
3,特点
按照自身逻辑结构,让那些不可能同时被访问的程序段共享同一个覆盖区。
必须由程序员声明覆盖结构,操作系统完成自动覆盖。
缺点:对用户不透明,增加了用户编程负担。
2,交换技术
交换(对换)技术的设计思想:内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)
1,在外出的什么位置保持被换出的进程
具有对换功能的操作系统中,通常把磁盘空间分为文件区和对换区两部分。文件区主要用于存放文件,主要追求存储空间的利用率,因此对文件区空间的管理采用离散分配方式;对换区空间只占磁盘空间的小部分,被换出的进程数据就存放在对换区。由于对换的速度直接影响到系统的整体速度,因此对换区空间的管理主要追求换入换出速度,因此通常对换区采用连续分配方式(学过文件管理章节后即可理解)。总之,对换区的I/O速度比文件区的更快。
2,什么时候应该交换
交换通常在许多进程运行且内存吃紧时进行,而系统负荷降低就暂停。例如:在发现许多进程运行时经常发生缺页,就说明内存紧张,此时可以换出一些进程;如果缺页率明显下降,就可以暂停换出。
3,应该换出哪些进程
可优先换出阻塞进程;可换出优先级低的进程;为了防止优先级低的进程在被调入内存后很快又被换出,有的系统还会考虑进程在内存的驻留时间(注意:PCB会常驻内存,不会被换出外存)
3,覆盖与交换的区别
覆盖是在同一个程序或进程中的
交换是只不同进程(或作业)之间的
3.1.4连续分配管理方式
1,单一连续分配
在单一连续分配方式中,内存被分为系统区和用户区。系统区通常位于内存的低地址部分,用于存放操作系统相关数据;用户区用于存放用户进程相关数据。
内存中只能有一道用户程序,用户程序独占整个用户区空间。
优点:
实现简单;无外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护(eg:早期的PC操作系统MS-DOS)。
缺点:
只能用于单用户、单任务的操作系统中;有内部碎片;存储器利用率极低。
tip:分配给某进程的内存区域中,如果有些部分没有用上,就是“内部碎片”
2,固定分区分配
在内存中装入多道程序,且这些程序之间又不会相互干扰,于是将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业,这样就形成了最早的、最简单的一种可运行多道程序的内存管理方式。
特点:
操作系统需要建立一个数据结构——分区说明表,来实现各个分区的分配与回收。每个表项对应一个分区,通常按分区大小排列。每个表项包括对应分区的大小、起始地址、状态(是否已分配)。
- 优点:
实现简单,无外部碎片。
- 缺点:
a.当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能;b.会产生内部碎片,内存利用率低。
两种分区方式:
- 分区大小相等
缺乏灵活性,但是很适合用于用一台计算机控制多个相同对象的场合
- 分区大小不等
分区大小不等:增加了灵活性,可以满足不同大小的进程需求。根据常在系统中运行的作业大小情况进行划分
3,动态分区分配
动态分区分配又称为可变分区分配。这种分配方式不会预先划分内存分区,而是在进程装入内存时根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。
动态分区分配没有内部碎片,但是有外部碎片。
内部碎片,分配给某进程的内存区域中,如果有些部分没有用上。
外部碎片,是指内存中的某些空闲分区由于太小而难以利用。
可以通过拼凑技术来解决外部碎片
1,操作系统用什么样的数据结构记录内存的使用情况
- 空闲分区表
每个空闲分区对应一个表项。表项中包含分区号、分区大小、分区起始地址等信息
- 空闲分区链
每个分区的起始部分和末尾部分分别设置前向指针和后向指针。起始部分处还可记录分区大小等信息
2,当很多空闲分区都满足需求时,一个选择哪个分区进行分配
把一个新作业装入内存时,须按照一定的动态分区分配算法,从空闲分区表(或空闲分区链)中选出一个分区分配给该作业。由于分配算法算法对系统性能有很大的影响,因此人们对它进行了广泛的研究。
3,如何进行分区的分配与回收
分区的分配修改空闲分区表或空闲分区链即可
分区的回收分为四种情况:
- 情况一:回收区的后面有一个相邻的空闲分区
两个相邻的空闲分区合并为一个
- 情况二:回收区的前面有一个相邻的空闲分区
两个相邻的空闲分区合并为一个
- 情况三:回收区的前、后各有一个相邻的空闲分区
三个相邻的空闲分区合并为一个
- 情况四:回收区的前后都没有相邻的空闲分区
新增一个表项
3.1.5动态分区分配算法
动态分区分配算法:在动态分区分配方式中,当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配
1,首次适应算法(First Fit)
算法思想:
每次都从低地址开始查找,找到第一个能满足大小的空闲分区。
如何实现:
空闲分区以地址递增的次序排列。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
分区排列顺序:
空闲分区以地址递增次序排列
优点:
综合看性能最好,算法开销小,回收分区后一般不需要对空闲分区队列重新排序
2,最佳适应算法(Best Fit)
算法思想:
由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。因此为了保证当“大进程”到来时能有连续的大片空间,可以尽可能多地留下大片的空闲区,即,优先使用更小的空闲区。
如何实现:
空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
分区排列顺序:
空闲分区以容量递增次序排列
优点:
会有更多的大分区被保留下来,更能满足大进程的需求
缺点:
会产生很多太小的,难以利用的碎片;算法开销大,回收分区后可能需要对空闲分区队列重新排序
3,最坏适应算法(Wrost Fit)
算法思想:
又称最大适应算法,为了解决最佳适应算法的问题——即留下太多难以利用的小碎片,可以在每次分配时优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,更方便使用。
如何实现:
空闲分区按容量递减次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
分区排列顺序:
空闲分区以容量第减次序排列
优点:
可以减少难以利用的小碎片
缺点:
大分区容易被用完,不利于大进程,算法开销大,回收分区后可能需要对空闲分区队列重新排序
4,邻近适应算法(Next Fit)
算法思想:
首次适应算法每次都从链头开始查找的。这可能会导致低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。如果每次都从上次查找结束的位置开始检索,就能解决上述问题。
如何实现:
空闲分区以地址递增的顺序排列(可排成一个循环链表)。每次分配内存时从上次查找结束的位置开始查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
分区排列顺序:
空闲分区以地址递增次序排列(可排列成循环链表)
优点:
不用每次都重低地址的小分区开始检索。算法开销小,回收分区后一般不需要对空闲分区队列重新排序
缺点:
邻近适应算法的规则可能会导致无论低地址、高地址部分的空闲分区都有相同的概率被使用,也就导致了高地址部分的大分区更可能被使用,划分为小分区,最后导致无大分区可用(最大适应算法的缺点)
3.1.6基本分页存储的基本概念(非连续分配管理)
1,基本分页存储的管理的思想
将内存空间分为一个个大小相等的分区(比如:每个分区4KB),每个分区就是一个“页框”(页框=页帧=内存块=物理块=物理页面)。每个页框有一个编号,即“页框号”(页框号=页帧号=内存块号=物理块号=物理页号),页框号从0开始。
将进程的逻辑地址空间也分为与页框大小相等的一个个部分,每个部分称为一个“页”或“页面”。每个页面也有一个编号,即“页号”,页号也是从0开始。
2,混淆概念
页、页面(进程的逻辑地址)
页号、页面号(进程的逻辑地址的编号)
页框、页帧、内存块、物理块、物理页面(内存空间的)
页框号、页帧号、物理页号、物理页号(内存空间的编号)
3,页表
作用:
为了能知道进程的每个页面在内存中存放的位置,操作系统要为每个进程建立一张页表。页表通常存放在PCB中
组成:
1.一个进程对应一张页表
2.进程的每个页面对应一个页表项
3.每个页表项由“页号”和“块号”组成
4.页表记录进程页面和实际存放的内存块之间的映射关系
5.每个页表项的长度是相同的
特点:
每个页表项的大小是相同的,页号是“隐含“的(类比数组)
4,逻辑地址结构
可以拆分成【页号,页内便宜量】
页号=逻辑地址/页面大小
页内偏移量=逻辑地址%页面大小
5,如何实现地址转换
1.计算出逻辑地址对应的【页号,页内偏移量】
2.找到对应页面在内存中的存放位置(查页表)
页面在内存中的起始地址(页面始址)=块号*内存块的大小
3.物理地址=页面始址+页内偏移量
3.1.7基本地址变换机构
在基本分页存储管理中实现逻辑地址到物理地址转换的一组硬件机构
基本地址变换机构可以借助进程的页表将逻辑地址转换为物理地址。
1,页表寄存器的作用
通常会在系统中设置一个页表寄存器(PTR),存放页表在内存中的起始地址F和页表长度M。进程未执行时,页表的始址和页表长度放在进程控制块(PCB)中,当进程被调度时,操作系统内核会把它们放到页表寄存器中。
2,地址变换的过程
注意:页面大小是2的整数幂设页面大小为L,逻辑地址A到物理地址E的变换过程如下:
①计算页号P和页内偏移量W(如果用十进制数手算,则P=A/L,W=A%L;但是在计算机实际运行时,逻辑地址结构是固定不变的,因此计算机硬件可以更快地得到二进制表示的页号、页内偏移量)
②比较页号P和页表长度M,若P≥M,则产生越界中断,否则继续执行。(注意:页号是从0开始的,而页表长度至少是1,因此P=M时也会越界)
③页表中页号P对应的页表项地址=页表起始地址F+页号P*页表项长度,取出该页表项内容b,即为内存块号。(注意区分页表项长度、页表长度、页面大小的区别。页表长度指的是这个页表中总共有几个页表项,即总共有几个页;页表项长度指的是每个页表项占多大的存储空间;页面大小指的是一个页面占多大的存储空间)
④计算E=b*L+W,用得到的物理地址E去访存。(如果内存块号、页面偏移量是用二进制表示的,那么把二者拼接起来就是最终的物理地址了)
3,其它小细节
页内偏移量位数与页面大小之间的关系(要能用其中一个条件推出另一个条件)
页式管理中地址是一维的
实际应用中,通常使一个页框恰好能放入整数个页表项
为了方便找到页表项,页表一般是放在连续的内存块中的
3.1.8具有快表的地址变换机构
是基本地址变换机构的改进版本(两次访问内存)
1,什么是快表
快表,又称联想寄存器(TLB,translation lookaside buffer),是一种访问速度比内存快很多的高速缓存(TLB不是内存!),用来存放最近访问的页表项的副本,可以加速地址变换的速度。与此对应,内存中的页表常称为慢表。
TLB和普通Cache的区别:
TLB中只有页表项的副本,而普通Cache中可能会有其它各种数据的副本
2,引入快表后,地址变换的过程
①算页号、页内偏移量
②检查页号合法性
③查快表。若命中,即可知道页面存放的内存块号,可直接进行⑤;若未命中则进行④
④查页表,找到页面存放的内存块号,并且将页表项复制到快表中
⑤根据内存块号与页内偏移量得到物理地址
⑥访问目标内存单元
3,局部性原理
由于查询快表的速度比查询页表的速度快很多,因此只要快表命中,就可以节省很多时间。因为局部性原理,一般来说快表的命中率可以达到90%以上。
- 时间局部性:
如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)
- 空间局部性:
一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的)
3.1.9两级页表
1,单级页表存在的问题
问题一:所有页表必须连续存放,页表过大时需要很大的连续空间(多级页表)
问题二:在一段时间内并非所有页面都用得到,因此没必要让整个页表常驻内存(虚拟存储技术)
2,两级页表
将长长的页表再分页
逻辑地址结构:(一级页号,二级页号,页内偏移量)
注意几个术语:页目录表=外层页表=顶级页表
3,如何实现地址变换
①按照地址结构将逻辑地址拆分成三部分
②从PCB中读出页目录表始址,根据一级页号查页目录表,找到下一级页表在内存中的存放位置
③根据二级页号查表,找到最终想访问的内存块号
④结合页内偏移量得到物理地址
4,几个细节
多级页表中,各级页表的大小不能超过一个页面。若两级页表不够,可以分更多级
多级页表的访存次数(假设没有快表机构):N级页表访问一个逻辑地址需要N+1次访存
3.1.10基本分段存储管理方式
1,什么是分段
进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言中,程序员使用段名来编程),每段从0开始编址
内存分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻。
分段系统的逻辑地址结构:段号(段名),段内地址(段内偏移量)
段号的位数决定了每个进程最多可以分几个段
段内地址位数决定了每个段的最大长度是多少
2,什么是段表
记录逻辑段到实际存储地址的映射关系
每个段对应一个段表项。各段表项长度相同,由段号(隐含)段长基址组成
3,如何实现地址转换
1.由逻辑地址得到段号、段内地址
2.段号与段表寄存器中的段长度比较,检查是否越界
3.由段表始址、段号找到对应段表项
4.根据段表中记录的段长,检查段内地址是否越界
5.由段表中的“基址+段内地址“得到最终的物理地址
6.访问目标单元
4,分段和分页的对比
分页对用户不可见,分段对用户可见
分页的地址空间是一维的,分段的地址空间是二维的
分段更容易实现信息的共享和保护(纯代码/可重入代码可以共享)
分页(单级页表)、分段访问一个逻辑地址都需要两次访存,分段存储中也可以引入快表机构
3.1.11段页式管理方式
1,分页、分段管理方式中最大的优缺点
优点 | 缺点 | |
---|---|---|
分页管理 | 内存空间利用率高,不会产生外部碎片,只会产生少量的页内碎片 | 不方便按照逻辑模式实现信息的共享和保护 |
分段式管理 | 很方便按照逻辑模块实现信息的共享和保护 | 如果段长过大,为其分配很大的连续空间会很不方便。另外,段式管理会产生外部碎片 |
2,分段+分页的结合——段页式管理方式
将地址空间按照程序自身的逻辑关系划分为若干个段,再将各段分为大小相等的页面
将内存空间分为与页面大小相等的一个个内存块,系统以块为单位为进程分配内存
逻辑地址:(段号,页号,页内偏移量)
段号的位数决定了每个进程最多可以分几个段
页号位数决定了每个段最大有多少页
页内偏移量决定了页面大小、内存块大小是多少
3,段表、页表
每个段对应一个段表项。各段表项长度相同,由段号(隐含)、页表长度、页表存放块号(页表起始地址)组成
每个页对应一个页表项。各页表项长度相同,由页号(隐含)、页面存放的内存块号组成
一个进程会对应一个段表,每个段表项会对应一个页表,因此一个进程可能会对应多个页表
4,如何实现地址变换
1.由逻辑地址得到段号、页号、页内偏移量
2.段号与段表寄存器中的段长度比较,检查是否越界
3.由段表始址、段号找到对应段表项
4.根据段表中记录的页表长度,检查页号是否越界
5.由段表中的页表地址、页号得到查询页表,找到相应页表项
6.由页面存放的内存块号、页内偏移量得到最终的物理地址
7.访问目标单元
5,访问一个逻辑地址所需访存次数
第一次——查段表、第二次——查页表、第三次——访问目标单元
可引入快表机构,以段号和页号为关键字查询快表,即可直接找到最终的目标页面存放位置。引入快表后仅需一次访存
3.2虚拟内存管理
3.2.1虚拟内存的基本概念
在传统存储管理方式的基础上引入了交换技术、覆盖技术,使得内存利用率有所提升,并且能从逻辑上扩充内存容量。
虚拟存储技术也可以实现内存空间的扩充
1,传统存储管理方式的特征、缺点
一次性:
作业必须一次性全部装入内存后才能开始运行。这会造成两个问题:
①作业很大时,不能全部装入内存,导致大作业无法运行;
②当大量作业要求运行时,由于内存无法容纳所有作业,因此只有少量作业能运行,导致多道程序并发度下降。
驻留性:
一旦作业被装入内存,就会一直驻留在内存中,直至作业运行结束。事实上,在一个时间段内,只需要访问作业的一小部分数据即可正常运行,这就导致了内存中会驻留大量的、暂时用不到的数据,浪费了宝贵的内存资源。
2,局部性原理
时间局部性:
如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)
空间局部性:
一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的,并且程序的指令也是顺序地在内存中存放的)
高速缓冲技术的思想:
将近期会频繁访问到的数据放到更高速的存储器中,暂时用不到的数据放在更低速存储器中。
3,虚拟内存的定义和特征
定义:
基于局部性原理,在程序装入时,可以将程序中很快会用到的部分装入内存,暂时用不到的部分留在外存,就可以让程序开始执行。在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。在操作系统的管理下,在用户看来似乎有一个比实际内存大得多的内存,这就是虚拟内存
特征:
-
多次性:无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。
-
对换性:在作业运行时无需一直常驻内存,而是允许在作业运行过程中,将作业换入、换出。
-
虚拟性:从逻辑上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量。
4,如何实现虚拟内存技术
虚拟内存技术,允许一个作业分多次调入内存。如果采用连续分配方式,会不方便实现。因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上。
传统内存存储管理和虚拟内存存储管理方式的区别
访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存(请求调页功能)
内存空间不够时,将内存中暂时用不到的信息换出到外存(页面置换功能)
虚拟内存的实现:
请求分页存储管理
请求分段存储管理
请求段页式存储管理
3.2.2请求分页管理方式
请求分页存储管理与基本分页存储管理的主要区别:
在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。(操作系统需要提供请求调页功能,将缺失的页面从外存调入内存)
若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。(操作系统需要提供页面置换的功能,将内存中暂时用不到的信息换出外存)
1,页表机制
与基本分页管理相比,请求分页管理中,为了实现“请求调页”,”页面置换“,请求分页存储管理的页表增加了下面几个表项
状态位:
表示页面是否已在内存中
访问字段:
记录最近被访问过几次,或记录上次访问的时间,供置换算法选择换出页面时参考
修改位:
表示页面调入内存后是否被修改过,只有修改过的页面才需在置换时写回外存
外存地址:
页面在外存中存放的位置
2,缺页中断机构
在请求分页系统中,每当要访问的页面不在内存时,便产生一个缺页中断,然后由操作系统的缺页中断处理程序处理中断。
此时缺页的进程阻塞,放入阻塞队列,调页完成后再将其唤醒,放回就绪队列。
如果内存中有空闲块,则为进程分配一个空闲块,将所缺页面装入该块,并修改页表中相应的页表项。
如果内存中没有空闲块,则由页面置换算法选择一个页面淘汰,若该页面在内存期间被修改过,则要将其写回外存。未修改过的页面不用写回外存。
缺页中断是因为当前执行的指令想要访问的目标页面未调入内存而产生的,因此属于内中断。
一条指令在执行期间,可能产生多次缺页中断。
3,地址变换机构
找到页表项是需要检查页面是否在内存中
若页面不再内存中,需要请求调页
若内存空间不够,还需换出页面
页面调入内存后,需要修改相应页表项
注意:快表中有的页面一定是在内存中的。若某个页面被换出外存,则快表中的相应表项也要删除,否则可能访问错误的页面。
4,补充细节
①只有“写指令”才需要修改“修改位”。并且,一般来说只需修改快表中的数据,只有要将快表项删除时才需要写回内存中的慢表。这样可以减少访存次数。
②和普通的中断处理一样,缺页中断处理依然需要保留CPU现场。
③需要用某种“页面置换算法”来决定一个换出页面(下节内容)
④换入/换出页面都需要启动慢速的I/0操作,可见,如果换入/换出太频繁,会有很大的开销。
⑤页面调入内存后,需要修改慢表,同时也需要将表项复制到快表中。
3.2.3页面置换算法
若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。
页面的换入、换出需要磁盘1/O,会有较大的开销,因此好的页面置换算法应该迫求更少的缺页率
1,最佳置换算法(OPT)
算法规则:
每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率。(至少
注意:
缺页时未必发生页面置换。若还有可用的空闲内存块,就不用进行页面置换。
优缺点:
缺页率最小,性能最好;但无法实现
2,先进先出置换算法(FIFO)
算法规则:
优先淘汰最先进入内存的页面
实现方法:
实现方法:把调入内存的页面根据调入的先后顺序排成一个队列,需要换出页面时选择队头页面即可。队列的最大长度取决于系统为进程分配了多少个内存块。
优缺点:
Belady异常一一当为进程分配的物理块数增大时,缺页次数不减反增的异常现象。
只有FIFO算法会产生Belady异常。另外,FIFO算法虽然实现简单,但是该算法与进程实际运行时的规律不适应,因为先进入的页面也有可能最经常被访问。因此,算法性能差
3,最近最久未使用置换算法(LRU)
算法规则:
每次淘汰的页面是最近最久未使用的页面
实现方法:
赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间t。当需要淘汰一个页面时,选择现有页面中t值最大的,即最近最久未使用的页面。
在手动做题时,若需要淘汰页面,可以逆向检查此时在内存中的几个页面号。在逆向扫描过程中最后一个出现的页号就是要淘汰的页面。
优缺点:
该算法的实现需要专门的硬件支持,虽然算法性能好,但是实现困难,开销大
4,时钟置换算法(CLOCK)
算法规则:
时钟置换算法是一种性能和开销较均衡的算法,,又称CLOCK算法,或最近未用算法(NRU,NotRecently Used)
算法实现:
- 简单的CLOCK算法实现方法:
为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位置为1。当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出;如果是1,则将它置为0,暂不换出,继续检查下一个页面,若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置为0后,再进行第二轮扫描(第二轮扫描中一定会有访问位为0的页面,因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描)
优缺点:
实现简单,算法开销小;但未考虑页面是否被修改过。
5,改进型的时钟置换算法
算法思想:
简单的时钟置换算法仅考虑到一个页面最近是否被访问过。事实上,如果被淘汰的页面没有被修改过,就不需要执行I/0操作写回外存。只有被淘汰的页面被修改过时,才需要写回外存。因此,除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/0操作。这就是改进型的时钟置换算法的思想。修改位=0,表示页面没有被修改过;修改位=1,表示页面被修改过。为方便讨论,用(访问位,修改位)的形式表示各页面状态。如(1,1)表示一个页面近期被访问过,且被修改过。
算法规则:
将所有可能被置换的页面排成一个循环队列
第一轮:从当前位置开始扫描到第一个(0,0)的帧用于替换。本轮扫描不修改任何标志位(第一优先级:最近没访问,且没修改的页面)
第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0,1)的帧用于替换。本轮将所有扫描过的帧访问位设为0(第二优先级:最近没访问,但修改过的页面)
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0,0)的帧用于替换。本轮扫描不修改任何标志位(第三优先级:最近访问过,但没修改的页面)
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0,1)的帧用于替换。(第四优先级:最近访问过,且修改过的页面)
由于第二轮已将所有帧的访问位设为0,因此经过第三轮、第四轮扫描一定会有一个帧被选中,因此改进型CLOCK置换算法选择一个淘汰页面最多会进行四轮扫描。
优缺点:
算法开销较小,性能也不错
3.2.4页面分配策略
1,驻留集
指请求分页存储管理中给进程分配的内存块的集合
在采用了虚拟存储技术的系统中,驻留集大小一般小于进程的总大小。
若驻留集太小,会导致缺页频繁,系统要花大量的时间来处理缺页,实际用于进程推进的时间很少。
若驻留集太大,又会导致多道程序并发度下降,资源利用率降低。
2,页面分配、置换策略
1,固定分配VS可变分配
- 固定分配:
操作系统为每个进程分配一组固定数目的物理块,在进程运行期间不再改变。即,驻留集大小不变
- 可变分配:
可变分配:先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少。即,驻留集大小可变。
2,局部置换VS全局置换
- 局部置换:
发生缺页时只能选进程自己的物理块进行置换。
- 全局置换:
可以将操作系统保留的空闲物理块分配给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程。
注意:全局置换意味着一个进程拥有的物理块数量必然会改变,因此不可能是固定分配
3,固定分配局部置换
系统为每个进程分配一定数量的物理块,在整个运行期间都不改变。若进程在运行中发生缺页,则只能从该进程在内存中的页面中选出一页换出,然后再调入需要的页面。这种策略的缺点是:很难在刚开始就确定应为每个进程分配多少个物理块才算合理。(采用这种策略的系统可以根据进程大小、优先级、或是根据程序员给出的参数来确定为一个进程分配的内存块数)
4,可变分配全局置换
可变分配全局置换:刚开始会为每个进程分配一定数量的物理块。操作系统会保持一个空闲物理块队列。当某进程发生缺页时,从空闲物理块中取出一块分配给该进程;若已无空闲物理块,则可选择一个未锁定的页面换出外存,再将该物理块分配给缺页的进程。采用这种策略时,只要某进程发生缺页,都将获得新的物理块,仅当空闲物理块用完时,系统才会选择一个未锁定的页面调出。被选择调出的页可能是系统中任何一个进程中的页,因此这个被选中的进程拥有的物理块会减少,缺页率会增加。
5,可变分配局部置换
刚开始会为每一个进程分配一定数量的物理块。当某进程发生缺页时,只允许从该进程自己的物理块中选出一个进行换出外存。如果进程在运行中频繁地缺页,系统会为该进程多分配 几个物理块,直至该进程缺页率趋势适当程度;反之,如果进程在运行中缺页率特别低,则可适当减 少分配给该进程的物理块。
可变分配全局置换:只要缺页就给分配新物理块
可变分配局部置换:要根据发生缺页的频率来动态地增加或减少进程的物理块
3,何时调入页面
1.预调页策略:
根据局部性原理,一次调入若干个相邻的页面可能比一次调入一个页面更高效。但如果提前调入的页面中大多数都没被访问过,则又是低效的。因此可以预测不久之后可能访问到的页面,将它们预先调入内存,但目前预测成功率只有50%左右。故这种策略主要用于进程的首次调入,由程序员指出应该先调入哪些部分。
2.请求调页策略:
进程在运行期间发现缺页时才将所缺页面调入内存。由这种策略调入的页面一定会被访问到,但由于每次只能调入一页,而每次调页都要磁盘1/0操作,因此I/0开销较大。
4,从何处调入页面
1.系统拥有足够的对换区空间:
页面的调入、调出都是在内存与对换区之间进行,这样可以保证页面的调入、调出速度很快。在进程运行前,需将进程相关的数据从文件区复制到对换区。
2.系统缺少足够的对换区空间:
凡是不会被修改的数据都直接从文件区调入,由于这些页面不会被修改,因此换出时不必写回磁盘,下次需要时再从文件区调入即可。对于可能被修改的部分,换出时需写回磁盘对换区,下次需要时再从对换区调入。
3.UNIX方式:
运行之前进程有关的数据全部放在文件区,故未使用过的页面,都可从文件区调入。若被使用过的页面需要换出,则写回对换区,下次需要时从对换区调入。
5,进程抖动(颠簸)现象
刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)
6,工作集
为进程分配的物理块太少,会使进程发生抖动现象。为进程分配的物理块太多,又会降低系统整体的并发度,降低某些资源的利用率。
为了研究为应该为每个进程分配多少个物理块,Denning 提出了进程“工作集”的概念
工作集:指在某段时间间隔里,进程实际访问页面的集合。
驻留集大小一般不能小于工作集大小。
3.2.5内存映射文件
1,内存映射文件是什么
操作系统向上层程序员提供的功能(系统调用)
-
方便程序员访问文件数据
-
方便多个进程共享同一个文件
2,传统的文件访问方式
open系统调用——打开文件
seek系统调用——将读写指针移到某个位置
read系统调用——从读写指针所指位置读入若干数据(从磁盘读入内存)
write系统调用—-将内存中的指定数据,写回磁盘(根据读写指针确定要写回什么位置)
3,内存映射文件的原理和作用
1,方便程序员访问文件数据
open系统调用—-打开文件
mmap系统调用——将文件映射到进程的虚拟地址空间
-
以访问内存的方式访问文件数据
-
文件数据的读入、写出由操作系统自动完成
-
进程关闭文件时,操作系统自动将文件被修改的数据写回磁盘
2,方便多个进程共享同一个文件
多个进程可以映射同一个文件,实现共享
在物理内存中,一个文件对应同一份数据,当一个进程修改文件数据时,另一个进程可以立马“看到”
4,内存映射文件的特性
进程可使用系统调用,请求操作系统将文件映射到进程的虚拟地址空间
以访问内存的方式读写文件
进程关闭文件时,操作系统负责将文件数据写回磁盘,并解除内存映射
多个进程可以映射同一个文件,方便共享
5,内存映射文件的优点
程序员编程更简单,已建立映射的文件,只需按访问内存的方式读写即可
文件数据的读入/写出完全由操作系统负责,I/O效率可以由操作系统负责优化
第四章文件管理
4.1文件系统基础
4.1.1初识文件管理
1,文件的定义
文件——就是一组有意义的信息/数据集合
2,文件的属性
- 文件名:
由创建文件的用户决定文件名,主要是为了方便用户找到文件,同一目录下不允许有重名文件。
- 标识符:
一个系统内的各文件标识符唯一,对用户来说毫无可读性,因此标识符只是操作系统用于区分各个文件的一种内部名称。
- 类型:
指明文件的类型
- 位置:
文件存放的路径(让用户使用)、在外存中的地址(操作系统使用,对用户不可见)
- 大小:
指明文件大小
-
创建时间、上次修改时间
-
文件所有者信息
-
保护信息:
对文件进行保护的访问控制信息
3,文件内部应该如何被组织起来(文件的逻辑结构)
1,无结构文件
无结构文件(如文本文件)——由一些二进制或字符流组成,又称“流式文件”
2,有结构文件
有结构文件(如数据库表)——由一组相似的记录组成,又称“记录式文件”
4,文件之间应该如何被组织起来(目录结构)
5,操作系统应向上提供哪些功能
创建文件(create系统调用)
删除文件(delete系统调用)
读文件((read系统调用)
写文件(write系统调用)
打开文件(open系统调用)
关闭文件(close系统调用)
6,文件应如何存放在外存中(文件的物理结构)
与内存一样,外存也是由一个个存储单元组成的,每个存储单元可以存储一定量的数据(如1B)。每个存储单元对应一个物理地址。
类似于内存分为一个个“内存块”,外存会分为一个个“块/磁盘块/物理块”。每个磁盘块的大小是相等的,每块一般包含2的整数幂个地址(如本例中,一块包含2^10个地址,即1KB)。同样类似的是,文件的逻辑地址也可以分为(逻辑块号,块内地址),操作系统同样需要将逻辑地址转换为外存的物理地址(物理块号,块内地址)的形式。块内地址的位数取决于磁盘块的大小
操作系统以“块”为单位为文件分配存储空间,因此即使一个文件大小只有10B,但它依然需要占用1KB的磁盘块。外存中的数据读入内存时同样以块为单位.
7,操作系统如何管理外存中的空闲块(存储空间的管理)
8,操作系统需要提供的其他文件管理功能(文件共享,文件保护)
文件共享:
使多个用户可以共享使用一个文件
文件保护:
如何保证不同的用户对文件有不同的操作权限
4.1.2文件的逻辑结构
所谓的“逻辑结构”,就是指在用户看来,文件内部的数据应该是如何组织起来的。
而“物理结构”指的是在操作系统看来,文件的数据是如何存放在外存中的。
1,无结构文件
无结构文件:文件内部的数据就是一系列二进制流或字符流组成。又称“流式文件”。如:Windows 操作系统中的.txt 文件。
文件内部的数据其实就是一系列字符流,没有明显的结构特性。因此也不用探讨无结构文件的“逻辑结构”问题。
2,有结构文件
有结构文件:由一组相似的记录组成,又称“记录式文件”。每条记录又若干个数据项组成。如:数据库表文件。一般来说,每条记录有一个数据项可作为关键字。根据各条记录的长度(占用的存储空间)是否相等,又可分为定长记录和可变长记录两种。
根据有结构文件中的各条记录在逻辑上如何组织,可以分为三类
1,顺序文件
文件中的记录一个接一个地顺序排列(逻辑上),记录可以是定长的或可变长的。各个记录在物理上可以顺序存储或链式存储。
顺序存储——逻辑上相邻的记录物理上也相邻(类似于顺序表)
链式存储——逻辑上相邻的记录物理上不一定相邻(类似于链表)
串结构
记录之间的顺序与关键字无关
顺序结构
记录之间的顺序按关键字顺序排列
可变长记录的顺序文件无法实现随机存取,定长记录可以
定长记录、顺序结构的顺序文件可以快速检索(根据关键字快速找到记录)
最大缺点:不方便增加/删除记录
2,索引文件
建立一张索引表,每个记录对应一个表项。各记录不用保持顺序,方便增加/删除记录
索引表本身就是定长记录的顺序文件,一个索引表项就是一条定长记录,因此索引文件可支持随机存取
若索引表按关键字顺序排列,则可支持快速检索
解决了顺序文件不方便增/删记录的问题,同时让不定长记录的文件实现了随机存取。但索引表可能占用很多空间
3,索引顺序文件
将记录分组,每组对应一个索引表项
检索记录时先顺序查索引表,找到分组,再顺序查找分组
当记录过多时,可建立多级索引表
4.1.3文件目录
1,文件目录的实现
一个文件对应一个FCB(文件控制块),一个FCB就是一个目录项,多个FCB组成文件目录
对目录的操作:搜索、创建文件、删除文件、显示文件、修改文件
2,目录结构
1,单级目录结构
一个系统只有一张目录表,不允许文件重名
2,两级目录结构
早期的多用户操作系统,采用两级目录结构。分为主文件目录(MFD,Master File Directory)和用户文件目录(UFD,User Flie Directory)。
不同用户的文件可以重名,但不能对文件进行分类
主文件目录记录用户名及相应用户文件目录的存放位置
两级目录结构允许不同用户的文件重名,也可以在目录上实现实现访问限制(检查此时登录的用户名是否匹配)。但是两级目录结构依然缺乏灵活性,用户不能对自己的文件进行分类
3,多级(树形)目录结构
不同目录下的文件可以重名,可以对文件进行分类,不方便文件共享
系统根据“文件路径"找到目标文件
从根目录出发的路径是“绝对路径"(“/照片/2015-08/自拍.jpg”)(“/照片/2015-08/自拍.jpg”)
从“当前目录出发的路径是“相对路径"
4,无环图目录结构
在树形目录结构的基础上,增加一些指向同一节点的有向边,使整个目录成为一个有向无环图。
可以更方便地实现多个用户间的文件共享。
可以用不同的文件名指向同一个文件,甚至可以指向同一个目录(共享同一目录下的所有内容)。需要为每个共享结点设置一个共享计数器,用于记录此时有多少个地方在共享该结点。用户提出删除结点的请求时,只是删除该用户的FCB、并使共享计数器减1,并不会直接删除共享结点。
只有共享计数器减为0时,才删除结点。
注意:共享文件不同于复制文件。在共享文件中,由于各用户指向的是同一个文件,因此只要其中一个用户修改了文件数据,那么所有用户都可以看到文件数据的变化。
3,索引结点(FCB的改进)
除了文件名之外的所有信息都放到索引结点中,每个文件对应一个索引结点
目录项中只包含文件名、索引结点指针,因此每个目录项的长度大幅减小
由于目录项长度减小,因此每个磁盘块可以存放更多个目录项,因此检索文件时磁盘/O的次数就少了很多
4.1.4文件的物理结构(文件分配方式)
即文件数据应该怎样被存放在外存中
类似于内存分页,磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”。很多操作系统中,磁盘块的大小与内存块、页面的大小相同。
在内存管理中,进程的逻地址空同被分为一个一个页面
同样的,在外存管理中,为了方便对文件数据的管理,文件的逻辑地址空间也被分为了一个一个的文件“块”。
于是文件的逻辑地址也可以表示为(逻辑块号,块内地址)的形式。
1,连续分配
方式
连续分配方式要求每个文件在磁盘上占有一组连续的块。
目录项内容
起始块号、文件长度
优点
- 顺序存取速度快
磁头移动时间短
- 支持顺序访问和随机访问(直接访问)
缺点
会产生碎片,不利于文件拓展
2,链接分配
链接分配采取离散分配的方式,可以为文件分配离散的磁盘块。分为隐式链接和显式链接两种。未明确默认是隐式链接。
1,隐式链接
除文件的最后一个盘块之外,每个盘块中都存有指向下一个盘块的指针。文件目录项包括文件第一块的指针和最后一块的指针。
优点:很方便文件拓展,不会有碎片问题,外存利用率高。
缺点:只支持顺序访问,不支持随机访问,查找效率低,指向下一个盘块的指针也需要耗费少量的存储空间。
2,显式链接
把用于链接文件各物理块的指针显式地存放在一张表中,即文件分配表(FAT,File Allocation Table)。一个磁盘只会建立一张文件分配表。开机时文件分配表放入内存,并常驻内。文件目录项存放文件的起始块号(物理块号)。
优点:很方便文件拓展,不会有碎片问题,外存利用率高,并且支持随机访问。相比于隐式链接来说,地址转换时不需要访问磁盘,因此文件的访问效率更高 。
缺点:文件分配表(FAT)的需要占用一定的存储空间。
3,索引分配
索引分配允许文件离散地分配在各个磁盘块中,系统会为每个文件建立一张索引表,索引表中记录了文件的各个逻辑块对应的物理块。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。
链接方案记录的是第一个索引块的块号,多层/混合索引记录的是顶级索引块的块号
支持随机访问,易于实现文件的拓展
索引表需占用一定的存储空间。访问数据块前需要先读入索引块。若采用链接方案,查找索引块时可能需要很多次读磁盘操作。
4,索引分配的补充
若文件太大,索引表项太多,可以采取以下三种方法解决:
①链接方案:
如果索引表太大,一个索引块装不下,那么可以将多个索引块链接起来存放。
缺点:若文件很大,索引表很长,就需要将很多个索引块链接起来。想要找到i号索引块,必须先依次读入0~i-1号索引块,这就导致磁盘l/0次数过多,查找效率低下。
②多层索引:
建立多层索引(原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。
采用K层索引结构,且顶级索引表未调入内存,则访问一个数据块只需要K+1次读磁盘操作。
缺点:即使是小文件,访问一个数据块依然需要K+1次读磁盘。
③混合索引:
多种索引分配方式的结合。例如,一个文件的顶级索引表中,既包含直接地址索引(直接指向数据块),又包含一级间接索引(指向单层索引表)、还包含两级间接索引(指向两层索引表)。
优点:对于小文件来说,访问一个数据块所需的读磁盘次数更少。
超级超级超级重要考点:
①要会根据多层索引、混合索引的结构计算出文件的最大长度(Key:各级索引表最大不能超过一个块);
②要能自己分析访问某个数据块所需要的读磁盘次数(Key:FCB中会存有指向顶级索引块的指针,因此可以根据FCB读入顶级索引块。每次读入下一级的索引块都需要一次读磁盘操作。另外,要注意题目条件—-顶级索引块是否已调入内存)
4.1.5文件的逻辑结构VS物理结构
逻辑结构
用户(文件创建者)的视角看到的样子
在用户看来,整个文件占用连续的逻辑地址空间
文件内部的信息组织完全由用户自己决定,操作系统并不关心
物理结构
由操作系统决定文件采用什么物理结构存储
操作系统负责将逻辑地址转变为(逻辑块号,块内偏移量)
的形式,并负责实现逻辑块号到物理块号的映射
4.1.6文件存存储空间管理
1,存储空间的划分与初始化
1,文件卷(逻辑卷)
存储空间的划分:将物理磁盘划分为一个个文件卷(逻辑卷、逻辑盘)如C盘,D盘
2,目录区与文件区
目录区主要存放文件目录信息(FCB)、用于磁盘存储空间管理的信息
文件区用于存放文件数据
2,空闲表法
空闲表中记录每个连续空闲区的起始盘块号、盘块数
分配时可采用首次适应、最佳适应等策略;回收时注意表项的合并问题
3,空闲链表法
1,空闲盘块链
以盘块勺单位组成一条空闲链
分配时从链头依次取出空闲块,回收时将空闲块挂到链尾
2,空闲盘区链
盘区为单位组成一条空闲链
分配时可采用首次适应、最佳适应等策略;回收时注意相邻空闲盘区合并的问题
4,位示图法
一个二进制位对应一个盘块。(字号,位号)或(行号,列号)与盘块号一一对应
重要考点:
要能够自己推出盘块号→(字号,位号)之间的相互转换公式
需要注意的题目条件:
二进制位O/1到底哪个代表空闲,哪个代表不空闲
字号、位号、盘块号到底是从0开始还是从1开始
5,成组链法
空闲表法、空闲链表法不适用于大型文件系统,因为空闲表或空闲链表可能过大。UNIX系统中采用了成组链接法对磁盘空闲块进行管理。
文件卷的目录区中专门用一个磁盘块作为“超级块”,当系统启动时需要将超级块读入内存。并且要保证内存与外存中的“超级块”数据一致。
4.1.7文件操作
1,创建文件(create系统调用)
1,在外存中找到文件所需的空间
2,在目录中创建该文件对应的目录项,目录项中包含了文件名,文件在外存的存放位置等信息。
2,删除文件(delete系统调用)
1,找到文件名对应的目录项
2,回收文件占用的磁盘块
3,从目录表中删除文件对应的目录项
3,打开文件(open系统调用)
将目录项中的信息复制到内存中的打开文件表中,并将打开文件表的索引号返回给用户
打开文件之后,对文件的操作不再需要每次都查询目录,可以根据内存中的打开文件表进行操作
每个进程有自己的打开文件表,系统中也有一张总的打开文件表
进程打开文件表中特有的属性:读写指针、访问权限(只读?读写?)
系统打开文件表中特有的属性:打开计数器(有多少个进程打开了该文件)
4,关闭文件(close系统调用)
1,将进程打开文件表中的相应表项删除
2,系统打开文件表的打开计数器减1,若打开计数器为0,则删除系统表的表项
5,读文件(read系统调用)
根据读指针、读入数据量、内存位置将文件数据从外存读入内存
6,写文件(write系统调用)
根据写指针、写出数据量、内存位置将文件数据从内存写出外存
4.1.8文件共享
操作系统为用户提供文件共享功能,可以让多个用户共享地使用同一个文件
1,硬链接(基于索引节点的共享方式)
各个用户的目录项指向同一个索引结点
索引结点中需要有链接计数count
某用户想删除文件时,只是删除该用户的目录项,且count–
只有count==0时才能真正删除文件数据和索引结点,否则会导致指针悬空
2,软链接(基于符号链接的共享方式)
在一个Link型的文件中记录共享文件的存放路径(Windows 快捷方式)
操作系统根据路径一层层查找目录,最终找到共享文件
即使软链接指向的共享文件已被删除,Link型文件依然存在,只是通过Link型文件中的路径去查找共享文件会失败(找不到对应目录项)
由于用软链接的方式访问共享文件时要查询多级目录,会有多次磁盘I/O,因此用软链接访问共享文件的速度要比硬链接更慢。
4.1.9文件保护
1,口令保护
为文件设置一个“口令”,用户想要访问文件时需要提供囗令,由系统验证囗令是否正确
实现开销小,但“口令”一般存放在FCB或索引结点中(也就是存放在系统中)因此不太安全
2,加密保护
用一个“密码"对文件加密,用户想要访问文件时,需要提供相同的“密码"才能正确的解密
安全性高,但加密/解密需要耗费一定的时间(Eg:异或加密)
3,访问控制
用一个访问控制表(ACL)记录各个用户(或各组用户)对文件的访问权限
对文件的访问类型可以分为:读/写/执行/删除等
实现灵活,可以实现复杂的文件保护功能
4.3文件系统
4.3.1文件系统的层次结构
1.用户接口:
用户需要通过操作系统提供的接口发出上述请求
2,文件目录系统:
由于用户提供的是文件的存放路径,因此需要操作系统一层一层地查找目录,找到对应的目录项
3.存取控制模块(存取控制验证层):
不同的用户对文件有不同的操作权限,因此为了保证安全,需要检查用户是否有访问权限
4.逻辑文件系统与文件信息缓冲区:
验证了用户的访问权限之后,需要把用户提供的“记录号”转变为对应的逻辑地址
5.物理文件系统:
知道了目标记录对应的逻辑地址后,还需要转换成实际的物理地址
6.设备管理程序模块:
要删除这条记录,必定要对磁盘设备发出请求
7.辅助分配模块:
删除这些记录后,会有一些盘块空闲,因此要将这些空闲盘块回收
4.3.2文件系统的全局结构(布局)
外存:
1,物理格式化,即低级格式化:划分扇区,检测坏扇区,并用备用扇区替换坏扇区
2,逻辑格式化后:磁盘分区(分卷Volume),完成各分区的文件系统初始化
注:逻辑格式化后,灰色部分就有实际数据了,白色部分还没有数据
内存
注:近期访问过的目录文件会缓存在内存中,不用每次都从磁盘读入,这样可以加快目录检索速度
分为用户区和内核区,其中:
用户区存放的是文件描述符
内核区存放的有:目录的缓存,系统打开文件表,进程打开文件表(存放在进程PCB中)
4.3.3虚拟文件系统&文件系统的挂载
1,虚拟文件系统的特点
①向上层用户进程提供统一标准的系统调用接口,屏蔽底层具体文件系统的实现差异
②VFS要求下层的文件系统必须实现某些规定的函数功能,如:open/read/write。一个新的文件系统想要在某操作系统上被使用,就必须满足该操作系统VFS的要求。
存在问题:不同的文件系统,表示文件数据结构各不相同。打开文件后,其在内存中的表示就不同,所以有了第三个特点
③每打开一个文件,VFS就在主存中新建一个vnode,用统一的数据结构表示文件,无论该文件存储在哪个文件系统。
注意:vnode只存在于主存中,而inode既会被调入主存,也会在外存中存储
打开文件后,创建vnode,并将文件信息复制到vnode中,添加函数功能指针到vnode,vnode的功能指针指向具体文件系统的函数功能。
2,文件系统挂载
即文件系统安装/装载–如何将一个文件系统挂载到操作系统中?
①在VFS中注册新挂载的文件系统。内存中的挂载表(mount table)包含每个文件系统的相关信息,包括文件系统类型、容量大小等。
②新挂载的文件系统,要向VFS提供一个函数地址列表
③将新文件系统加到挂载点(mountpoint),也就是将新文件系统挂载在某个父目录下。
第五章输入输出设备管理
5.1输入输出管理概述
5.1.1 I/O设备的基本概念和分类
1,什么是I/O设备
I/O设备就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部件。
Write操作:向外部设备写出数据
Read操作:从外部设备读入数据
2,按使用特性分类
1,人机交互类设备
如鼠标,键盘,打印机等等,数据传输速度慢。
2,存储设备
如移动硬盘,光盘等等,数据传输速度快
3,网络通信设备
调制解调器,传输速度介于上述两者之间
3,按传输速率分类
1,低速设备
2,中速设备
3,高速设备
4,按信息交换的单位分类
1,块设备
块设备:如磁盘等——数据传输的基本单位是“块”
传输速率较高,可寻址,即对它可随机地读/写任一块
2,字符设备
字符设备:鼠标、键盘等—数据传输的基本单位是字符
传输速率较慢,不可寻址,在输入/输出时常采用中断驱动方式
5.1.2 I/O控制器
I/O设备由机械部件和电子部件(I/O控制器、设备控制器)组成。
I/O设备的机械部件主要用来执行具体I/O操作。
如我们看得见摸得着的鼠标/键盘的按钮;显示器的LED屏;移动硬盘的磁臂、磁盘盘面。
I/O设备的电子部件通常是一块插入主板扩充槽的印刷电路板。
1,主要功能
CPU无法直接控制I/O设备的机械部件,因此I/O设备还要有一个电子部件作为CPU和/O设备机械部件之间的“中介”,用于实现CPU对设备的控制。
这个电子部件就是I/O控制器,又称设备控制器。CPU可控制I/O控制器,又由I/O控制器来控制设备的机械部件。
1,接受和识别CPU发出的命令
如CPU发来的read/write命令,I/O控制器中会有相应的控制寄存器来存放命令和参数
2,向CPU报告设备的状态
I/O控制器中会有相应的状态寄存器,用于记录I/0设备的当前状态。如:1表示空闲,0表示忙碌
3,数据交换
I/O控制器中会设置相应的数据寄存器。
输出时,数据寄存器用于暂存CPU发来的数据,之后再由控制器传送设备。
输入时,数据寄存器用于暂存设备发来的数据,之后CPU从数据寄存器中取走数据。
4,地址识别
类似于内存的地址,为了区分设备控制器中的各个寄存器,也需要给各个寄存器设置一个特定的“地址”。l/O控制器通过CPU提供的“地址”来判断CPU要读/写的是哪个寄存器
2,组成
1,CPU与控制器的接口
用于实现CPU与控制器之间的通信。CPU通过控制线发出命令;通过地址线指明要操作的设备:通过数据线来取出(输入)数据,或放入(输出)数据
2,I/O逻辑
负责接收和识别CPU的各种命令(如地址译码),并负责对设备发出命令
3,控制器与设备的接口
用于实现控制器与设备之间的通信
3,两种寄存器编址方式
值得注意的小细节:
①一个I/0控制器可能会对应多个设备;
②数据寄存器、控制寄存器、状态寄存器可能有多个(如:每个控制/状态寄存器对应一个具体的设备),且这些寄存器都要有相应的地址,才能方便CPU操作。有的计算机会让这些寄存器占用内存地址的一部分,称为内存映像I/O;另一些计算机则采用I/0专用地址,即寄存器独立编址。
1,内存映射I/O
控制器中的寄存器与内存统一编制
可以采用对内存进行操作的指令来对控制器进行操作
2,寄存器独立编址
控制器中的寄存器独立编制
需要设置专门的指令来操作控制器
5.1.3 I/O控制方式
1,程序直接控制方式
1,完成一次读/写操作的流程(轮询)
CPU向控制器发出命令
将I/O状态信息读入CPU寄存器
设备可能出现错误
将数据寄存器中的内容读入CPU寄存器
将CPU寄存器中的内容写到主存中
2,CPU干预的频率
很频繁,l/O操作开始之前、完成之后需要CPU介入,并且在等待I/O完成的过程中CPU需要不断地轮询检查。
3,数据传送的单位
每次读/写一个字
4,数据的流向
读操作(数据输入):I/O设备→CPU寄存器→内存
写操作(数据输出):内存→CPU寄存器→I/O设备
每个字的读/写都需要CPU的帮助
5,主要的优缺点
- 优点:
实现简单。在读/写指令之后,加上实现循环检查的一系列指令即可(因此才称为“程序直接控制方式”)
- 缺点:
CPU和I/O设备只能串行工作,CPU需要一直轮询检查,长期处于“忙等”状态,CPU利用率低。
2,中断驱动方式
1,完成一次读/写操作的流程
引入中断机制。由于I/o设备速度很慢,因此在CPU发出读/写命令后,可将等待I/O的进程阻塞,先切换到别的进程执行。
当1/O完成后,控制器会向CPU发出一个中断信号,CPU检测到中断信号后,会保存当前进程的运行环境信息,转去执行中断处理程序处理该中断。
处理中断的过程中,CPU从I/O控制器读一个字的数据传送到CPU寄存器,再写入主存。
接着,CPU恢复等待I/O的进程(或其他进程)的运行环境,然后继续执行。
2,CPU干预的频率
每次I/O操作开始之前、完成之后需要CPU介入。
等待I/O完成的过程中CPU可以切换到别的进程执行。
3,数据传送的单位
每次读/写一个字
4,数据的流向
读操作(数据输入):l/O设备→CPU寄存器→内存
写操作(数据输出):内存→CPU寄存器→I/O设备
5,主要的优缺点
- 优点:
与“程序直接控制方式”相比,在“中断驱动方式”中,l/O控制器会通过中断信号主动报告I/O已完成,CPU不再需要不停地轮询。
CPU和I/O设备可并行工作,CPU利用率得到明显提升。
- 缺点:
每个字在I/O设备与内存之间的传输,都需要经过CPU。而频繁的中断处理会消耗较多的CPU时间。
3,DMA方式
与“中断驱动方式”相比,DMA方式(Direct Memory Access,直接存储器存取。主要用于块设备的I/O控制)有这样几个改进:
①数据的传送单位是“块”。不再是一个字、一个字的传送;
②数据的流向是从设备直接放入内存,或者从内存直接到设备。不再需要CPU作为“快递小哥”。
③仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。
1,完成一次读/写操作的流程
CPU指明此次要进行的操作(如:读操作),并说明要读入多少数据、数据要存放在内存的什么位置、数据在外部设备上的地址(如:在磁盘上的地址)
DMA控制器会根据CPU提出的要求完成数据的读/写工作,整块数据的传输完成后,才向CPU发出中断信号。
CPU发出I/O命令后可以做其他事,本次I/O完成后DMA控制器发出中断信号
- 注意:
DMA控制器是一种特殊的I/O控制器,和I/O控制器一样都由三个部分组成
DR(Data Register,数据寄存器):暂存从设备到内存,或从内存到设备的数据。
MAR(Memory Address Register,内存地址寄存器):在输入时,MAR表示数据应放到内存中的什么位置;输出时MAR表示要输出的数据放在内存中的什么位置。
DC(Data Counter,数据计数器):表示剩余要读/写的字节数。
CR(Command Register,命令/状态寄存器):用于存放CPU发来的I/O命令,或设备的状态信息。
2,CPU干预的频率
仅在传送一个或多个数据块的开始和结束时,才需要CPU干预。
3,数据传送的单位
每次读/写一个或多个块(注意:每次读写的只能是连续的多个块,且这些块读入内存后在内存中也必须是连续的)
4,数据的流向
读操作(数据输入):I/O设备→内存
写操作(数据输出):内存→I/O设备
5,主要的优缺点
- 优点:
数据传输以“块”为单位,CPU介入频率进一步降低。数据的传输不再需要先经过CPU再写入内存,数据传输效率进一步增加。CPU和/O设备的并行性得到提升。
- 缺点:
CPU每发出一条I/O指令,只能读/写一个或多个连续的数据块。如果要读/写多个离散存储的数据块,或者要将数据分别写到不同的内存区域时,CPU要分别发出多条I/O指令,进行多次中断处理才能完成。
4,通道控制方式
通道:一种硬件,可以理解为是“弱鸡版的CPU”。通道可以识别并执行一系列通道指令
与CPU相比,通道可以执行的指令很单一,并且通道程序是放在主机内存中的,也就是说通道与CPU共享内存
1,完成一次读/写操作的流程.
①CPU向通道发出I/O指令。指明通道程序在内存中的位置,并指明要操作的是哪个i/O设备。之后CPU就切换到其他进程执行了
②通道执行内存中的通道程序(其中指明了要读入/写出多少数据,读/写的数据应放在内存的什么位置等信息)
③通道执行完规定的任务后,向CPU发出中断信号,之后CPU对中断进行处理
2,CPU干预的频率
极低,通道会根据CPU的指示执行相应的通道程序,只有完成一组数据块的读/写后才需要发出中断信号,请求CPU干预。
3,数据传送的单位
每次读/写一组数据块
4,数据的流向
读操作(数据输入):I/O设备→内存
写操作(数据输出):内存→I/O设备
5,主要的优缺点
缺点:实现复杂,需要专门的通道硬件支持。
优点:CPU、通道、l/O设备可并行工作,资源利用率很高。
5.1.4I/O软件层次结构
每一层会利用其下层提供的服务,实现某些功能,并屏蔽实现的具体细节,向高层提供服务(“封装思想”)
1,用户层软件
用户层软件实现了与用户交互的接口,用户可直接使用该层提供的、与I/O操作相关的库函数对设备进行操作
用户层软件将用户请求翻译成格式化的1/0请求,并通过“系统调用”请求操作系统内核的服务
2,设备独立层软件
设备独立性软件,又称设备无关性软件。与设备的硬件特性无关的功能几乎都在这一层实现。
主要实现的功能:
①向上层提供统一的调用接口(如read/write系统调用)
②设备的保护
原理类似与文件保护。设备被看做是一种特殊的文件,不同用户对各个文件的访问权限是不一样的,同理,对设备的访问权限也不一样。
③差错处理
设备独立性软件需要对一些设备的错误进行处理
④设备的分配与回收
⑤数据缓冲区管理
可以通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异
⑥建立逻辑设备名到物理设备名的映射关系:根据设备类型选择调用相应的驱动程序
设备独立性软件需要通过“逻辑设备表(LUT,Logical UnitTable)”来确定逻辑设备对应的物理设备,并找到该设备对应的设备驱动程序。
操作系统系统可以采用两种方式管理逻辑设备表(LUT):
第一种方式,整个系统只设置一张LUT,这就意味着所有用户不能使用相同的逻辑设备名,因此这种方式只适用于单用户操作系统。
第二种方式,为每个用户设置一张LUT,各个用户使用的逻辑设备名可以重复,适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程,而LUT就存放在用户管理进程的PCB中。
3,设备驱动程序
主要负责对硬件设备的具体控制,将上层发出的一系列命令(如read/write)转化成特定设备“能听得懂”的一系列操作。包括设置设备寄存器;检查设备状态等。
不同的I/0设备有不同的硬件特性,具体细节只有设备的厂家才知道。因此厂家需要根据设备的硬件特性设计并提供相应的驱动程序。
4,中断处理程序
当I/O任务完成时,I/O控制器会发送一个中断信号,系统会根据中断信号类型找到相应的中断处理程序并执行。中断处理程序的处理流程如下:
5,硬件
5.1.5 输入/输出应用程序接口&设备驱动程序接口
1,输入输出应用程序接口
用户层的应用程序无法用一个统一的系统调用接口来完成所有类型设备的I/O
1,字符设接口
get/put系统调用:向字符设备读/写一个字符
2,块设备接口
read/write 系统调用:向块设备的读写指针位置读/写多个字符;
seek系统调用:修改读写指针位置
3,网络设备接口
网络设备接囗,又称“网络套接字(socket)接口”socket系统调用:创建一个网络套接字,需指明网络协议(TCP?UDP?)
bind:将套接字绑定到某个本地“端口”
connect:将套接字连接到远程地址
read/write:从套接字读/写数据
4,补充:阻塞I/0和非阻塞I/O
阻塞1/0:应用程序发出l/0系统调用,进程需转为阻塞态等待。
eg:字符设备接口——从键盘读一个字符get
非阻塞l/O:应用程序发出I/0系统调用,系统调用可迅速返回,进程无需阻塞等待。
eg:块设备接口——往磁盘写数据write
2,设备驱动程序接口
不同的操作系统,对设备驱动程序接口的标准各不相同。
设备厂商必须根据操作系统的接口要求,开发相应的设备驱动程序,设备才能被使用。
5.2 I/O核心子系统
5.2.1 概述I/O核心子系统
1,定义
设备独立性软件,设备驱动程序,中断处理程序这三个部分属于操作系统的内核部分,即“I/O系统”或称“I/O核心子系统”
2,不同区层次的技术
应用层——假脱机技术(SPOOLing技术)
设备独立性软件——I/O调度,设备保护,设备分配与回收,缓冲区管理(即缓冲和高速缓存)
2,I/O调度
l/O调度:用某种算法确定一个好的顺序来处理各个l/0请求。
如:磁盘调度(先来先服务算法、最短寻道优先算法、SCAN算法、C-SCAN算法、LOOK算法、C-LOOK算法)。当多个磁盘I/O请求到来时,用某种调度算法确定满足l/O请求的顺序。
同理,打印机等I/O设备也可以用先来先服务算法、优先级算法、短作业优先等算法来确定/0调度顺序。
3,设备保护
操作系统需要实现文件保护功能,不同的用户对各个文件有不同的访问权限(如:只读、读和写等)。
在UNIX系统中,设备被看做是一种特殊的文件,每个设备也会有对应的FCB。当用户请求访问某个设备时,系统根据FCB中记录的信息来判断该用户是否有相应的访问权限,以此实现“设备保护”的功能。(参考“文件保护”小节)
5.2.2假脱机技术(SPOOLing技术)
1,脱机技术
外围控制机+更高速的设备——磁带
在外围控制机的控制下,慢速输入设备的数据先被输入到更快速的磁带上。之后主机可以从快速的磁带上读入数据,从而缓解了速度矛盾
作用:缓解设备与CPU的速度矛盾,实现预输入、缓输出
Tips:为什么称为“脱机”-—脱离主机的控制进行的输入/输出操作。
2,假脱机技术
“假脱机技术”,又称“SPOOLing技术”是用软件的方式模拟脱机技术。
1,SPOOLing系统的组成如下:
- 在磁盘上开辟出两个存储区域——“输入井”和“输出井”
“输入井”模拟脱机输入时的磁带,用于收容I/0设备输入的数据
“输出井”模拟脱机输出时的磁带,用于收容用户进程输出的数据
- 要实现SPOOLing技术,必须要有多道程序技术的支持。系统会建立“输入进程”和“输出进程”
“输入进程”模拟脱机输入时的外围控制机
“输出进程”模拟脱机输出时的外围控制机
2,实现
输入井和输出井——模拟脱机输入/输出时的磁带
输入进程和输出进程——模拟脱机输入/输出时的外围控制机
输入缓冲区和输出缓冲区——内存中的缓冲区,输入、输出时的“中转站”
3,共享打印机
独占式设备——只允许各个进程串行使用的设备。一段时间内只能满足一个进程的请求。
共享设备一一允许多个进程“同时”使用的设备(宏观上同时使用,微观上可能是交替使用)。可以同时满足多个进程的使用请求。
打印机是种“独占式设备”,但是可以用SPOOLing技术改造成“共享设备”
1,实现方法
当多个用户进程提出输出打印的请求时,系统会答应它们的请求,但是并不是真正把打印机分配给他们,而是由假脱机管理进程为每个进程做两件事:
(1)在磁盘输出井中为进程申请一个空闲缓冲区(也就是说,这个缓冲区是在磁盘上的),并将要打印的数据送入其中;
(2)为用户进程申请一张空白的打印请求表,并将用户的打印请求填入表中(其实就是用来说明用户的打印数据存放位置等信息的),再将该表挂到假脱机文件队列上。当打印机空闲时,输出进程会从文件队列的队头取出一张打印请求表,并根据表中的要求将要打印的数据从输出井传送到输出缓冲区,再输出到打印机进行打印。用这种方式可依次处理完全部的打印任务
2,效果
虽然系统中只有一个台打印机,但每个进程提出打印请求时,系统都会为在输出井中为其分配一个存储区(相当于分配了一个逻辑设备),使每个用户进程都觉得自己在独占一台打印机,从而实现对打印机的共享。SPOOLing技术可以把一台物理设备虚拟成逻辑上的多台设备,可将独占式设备改造成共享设备。
5.2.3设备的分配与回收
1,应考虑的因素
1,设备固有属性
设备的固有属性可分为三种:独占设备、共享设备、虚拟设备。
- 独占设备
一个时段只能分配给一个进程(如打印机)
- 共享设备
可同时分配给多个进程使用(如磁盘),各进程往往是宏观上同时共享使用设备,而微观上交替使用。
- 虚拟设备
采用SPOOLing技术将独占设备改造成虚拟的共享设备,可同时分配给多个进程使用(如采用SPOOLing技术实现的共享打印机)
2,设备分配算法
先来先服务
优先级高者优先
短任务优先
3,设备分配中的安全性
从进程运行的安全性上考虑,设备分配有两种万式:
- 安全分配方式:
为进程分配一个设备后就将进程阻塞,本次I/O完成后才将进程唤醒。(eg:考虑进程请求打印机打印输出的例子)
一个时段内每个进程只能使用一个设备
优点:破坏了“请求和保持”条件,不会死锁
缺点:对于一个进程来说,CPU和I/O设备只能串行工作
- 不安全分配方式
进程发出I/0请求后,系统为其分配I/0设备,进程可继续执行,之后还可以发出新的I/O请求。只有某个I/O请求得不到满足时才将进程阻塞。
一个进程可以同时使用多个设备
优点:进程的计算任务和1/0任务可以并行处理,使进程迅速推进
缺点:有可能发生死锁(死锁避免、死锁的检测和解除)
2,静态分配与动态分配
1,静态分配
进程运行前为其分配全部所需资源,运行结束后归还资源
由于破坏了“请求和保持”条件,不会发生死锁。
2,动态分配
进程运行过程中动态申请设备资源
3,设备分配管理中的数据结构
一个通道可控制多个设备控制器,每个设备控制器可控制多个设备。
设备控制表(DCT)
每个设备对应一张DCT,关键字段:类型/标识符(即物理设备名)/状态/指向COCT的指针(每个设备由一个控制器控制,该指针可找到相对应控制器的信息)/重复执行此时或时间/等待队列指针(指向正在等待该设备的进程队列(由进程PCB组成队列))
控制器控制表(COCT)
每个控制器对应一张COCT,关键字段:控制器标识符(各个控制器的唯一ID)/状态/指向CHCT的指针/等待队列指针(指向正在等待该控制器的进程队列)
通道控制表(CHCT)
每个控制器对应一张CHCT,关键字段:状态/等待队列指针
系统设备表(SDT)
记录整个系统中全部设备的情况,每个设备对应一个表目,关键字段:设备类型/标识符/DCT/驱动程序入口
4,设备分配的步骤
①根据进程请求的逻辑设备名查找SDT(注:用户编程时提供的逻辑设备名其实就是“设备类型”)
②查找SDT,找到用户进程指定类型的、并且空闲的设备,将其分配给该进程。操作系统在逻辑设备表(LUT)中新增一个表项。
③根据DCT找到COCT,若控制器忙碌则将进程PCB挂到控制器等待队列中,不忙碌则将控制器分配给进程。
④根据COCT找到CHCT,若通道忙碌则将进程PCB挂到通道等待队列中,不忙碌则将通道分配给进程。
注:只有设备、控制器、通道三者都分配成功时·这次设备分配才算成功·之后便可启动I/O设备进行数据传送。
缺点:
①用户编程时必须使用“物理设备名”,底层细节对用户不透明,不方便编程。
②若换了一个物理设备,则程序无法运行。
③若进程请求的物理设备正在忙碌,则即使系统中还有同类型的设备,进程也必须阻塞等待。
5,设备分配步骤的改进
用户编程时使用逻辑设备名申请设备,操作系统负责实现从逻辑设备名到物理设备名的映射(通过LUT)
逻辑设备表设置的问题
- 整个系统只有一张LUT:
各用户所用的逻辑设备名不允许重复逻辑设备表的设置问题
- 每个用户一张LUT:
各个用户的逻辑设备名可重复
5.2.4缓冲区管理
1,缓冲区的概念
1,缓冲区的定义
缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可利用内存作为缓冲区。
使用硬件作为缓冲区的成本较高,容量也较小,一般仅用在对速度要求非常高的场合(如存储器管理中所用的联想寄存器,由于对页表的访问频率极高,因此使用速度很快的联想寄存器来存放页表项的副本)
一般情况下,更多的是利用内存作为缓冲区,“设备独立性软件”的缓冲区管理就是要组织管理好这些缓冲区。
2,缓冲区的作用
-
缓和CPU与I/O设备之间速度不匹配的矛盾
-
减少对CPU的中断频率,放宽对CPU中断响应时间的限制
-
解决数据粒度不匹配的问题(如:输出进程每次可以生成一块数据,但I/O设备每次只能输出一个字符)
-
提高CPU与I/O设备之间的并行性
2,单缓冲
假设某用户进程请求某种块设备读入若干块的数据。若采用单缓冲的策略,操作系统会在主存中为其分配一个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一个块)。
注意:当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出:当缓冲区为空时,可以往缓冲区冲入数据,但必须把缓冲区充满以后,才能从缓冲区把数据传出。
设备一(T)一缓冲区一(M)一工作区一(C)一处理
处理一块数据平均耗时 Max(C,T)+M
分析问题的初始状态:工作区满,缓冲区空
3,双缓冲
假设某用户进程请求某种块设备读入若干块的数据。若采用双缓冲的策略,操作系统会在主存中为其分配两个缓冲区(若题目中没有特别说明,一个缓冲区的大小就是一个块)
双缓冲题目中,假设初始状态为:工作区空,其中一个缓冲区满,另一个缓冲区空
结论:采用双缓冲策略,处理一个数据块的平均耗时为Max(T,C+M)
4,循环缓冲
将多个大小相等的缓冲区链接成一个循环队列。
in指针,指向下一个可以冲入数据的空缓冲区
out指针,指向下一个可以取出数据的满缓冲区
5,缓冲池
1,三个队列:
空缓冲队列、输入队列、输出队列
2,四种工作缓冲区
用于收容输入数据的工作缓冲区、用于提取输入数据的工作缓冲区
用于收容输出数据的工作缓冲区、用于提取输出数据的工作缓冲区
①输入进程请求输入数据
②计算进程想要取得一块输入数据
③计算进程想要将准备好的数据冲入缓冲区
④输出进程请求输出数据
5.3磁盘和固态硬盘
5.3.1磁盘的结构
1,磁盘,磁道,扇区的概念
1,磁盘
磁盘的表面由一些磁性物质组成,可以用这些磁性物质来记录二进制数据
2,磁道
磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道。
3,扇区
一个磁道又被划分成一个个扇区,每个扇区就是一个“磁盘块”。各个扇区存放的数据量相同(如1KB)
最内侧磁道上的扇区面积最小,因此数据密度最大
2,如何在磁盘中读/写数据
需要把“磁头”移动到想要读/写的扇区所在的磁道。
磁盘会转起来,让目标扇区从磁头下面划过,才能完成对扇区的读/写操作。
3,盘面,柱面的概念
磁盘由多个盘片“摞”起来,一个盘片可能有两个盘面
所有盘面中相对位置相同的磁道组成柱面
所有的磁头都是连在同一个磁臂上的,因此所有磁头只能“共进退”
4,磁盘的物理地址
可用(柱面号,盘面号,扇区号)来定位任意一个“磁盘块”。在“文件的物理结构”小节中,我们经常提到文件数据存放在外存中的几号块,这个块号就可以转换成(柱面号,盘面号,扇区号)的地址形式。
可根据该地址读取一个“块”
①根据“柱面号”移动磁臂,让磁头指向指定柱面;
②激活指定盘面对应的磁头;
③磁盘旋转的过程中,指定的扇区会从磁头下面划过,这样就完成了对指定扇区的读/写。
5,磁盘的分类
1,根据磁头是否可移动
固定头磁盘(每个磁道有一个磁头)
移动头磁盘(每个盘面只有一个磁头)
2,根据盘片是否可更换
盘片可以更换的称为可换盘磁盘
盘片不可更换的称为固定盘磁盘
5.3.2磁盘调度算法
1,一次性磁盘读/写操作需要的时间
1,寻找时间(寻道时间)
寻找时间(寻道时间)Ts:在读/写数据前,将磁头移动到指定磁道所花的时间。
①启动磁头臂是需要时间的。假设耗时为s;
②移动磁头也是需要时间的。假设磁头匀速移动,每跨越一个磁道耗时为m,总共需要跨越n条磁道。则:寻道时间Ts=s+m*n
现在的硬盘移动一个磁道大约需要0.2ms,磁臂启动时间约为2ms
2,延迟时间
通过旋转磁盘,使磁头定位到目标扇区所需要的时间。设磁盘转速为r(单位:转/秒,或转/分),则平均所需的延迟时间TR=(1/2)*(1/r)=1/2r。
1/r就是转一圈需要的时间。找到目标扇区平均需要转半圈,因此再乘以1/2
3,传输时间
从磁盘读出或向磁盘写入数据所经历的时间,假设磁盘转速为r,此次读/写的字节数为b,每个磁道上的字节数为N。则:传输时间T1=(1/r)*(b/N)=b/(rN)
2,磁盘调度算法
延迟时间和传输时间都与磁盘转速相关,且为线性相关。而转速是硬件的固有属性,因此操作系统也无法优化延迟时间和传输时间。
但是操作系统的磁盘调度算法会直控影响寻道时间。
1,先来先服务(FCFS)
根据进程请求访问磁盘的先后顺序进行调度。
优点:公平;如果请求访问的磁道比较集中的话,算法性能还算过的去。
缺点:如果有大量进程竞争使用磁盘,请求访问的磁道很分散,则FCFS在性能上很差,寻道时间长。
2,最短寻找时间优先(SSTF)
SSTF算法会优先处理的磁道是与当前磁头最近的磁道。可以保证每次的寻道时间最短,但是并不能保证总的寻道时间最短。(其实就是贪心算法的思想,只是选择眼前最优,但是总体未必最优)
优点:性能较好,平均寻道时间短。
缺点:可能产生“饥饿”现象。
3,扫描算法(电梯算法、SCAN)
SSTF算法会产生饥饿的原因在于:磁头有可能在一个小区域内来回来去地移动。为了防止这个问题,
可以规定,只有磁头移动到最外侧磁道的时候才能往内移动,移动到最内侧磁道的时候才能往外移
动。这就是扫描算法(SCAN)的思想。由于磁头移动的方式很像电梯,因此也叫电梯算法。
优点:性能较好,平均寻道时间较短,不会产生饥饿现象
缺点:
①只有到达最边上的磁道时才能改变磁头移动方向
②SCAN算法对于各个位置磁道的响应频率不平均
4,循环扫描算法(C-SCAN)
SCAN算法对于各个位置磁道的响应频率不平均,而C-SCAN算法就是为了解决这个问题。规定只有磁头朝某个特定方向移动时才处理磁道访问请求,而返回时直接快速移动至起始端而不处理任何请求。
优点:比起SCAN来,对于各个位置磁道的响应频率很平均。
缺点:只有到达最边上的磁道时才能改变磁头移动方向。
5,LOOK算法
SCAN算法的改进,只要在磁头移动方向上不再有请求,就立即改变磁头方向。
优点:比起SCAN算法来,不需要每次都移动到最外侧或最内侧才改变磁头方向,使寻道时间进一步缩短。
6,C-LOOK算法
C-SCAN算法的改进,只要在磁头移动方向上不再有请求,就立即让磁头返回
若题目中无特别说明,则SCAN就是LOOK,C-SCAN就是C-LOOK
5.3.3减少磁盘延迟时间的方法
磁头读入一个扇区数据后需要一小段时间处理,如果逻辑上相邻的扇区在物理上也相邻,则读入几个连续的逻辑扇区,可能需要很长的“延迟时间”。
1,交替编号
- 具体做法:
让编号相邻的扇区在物理上不相邻
- 原理:
读取完一个扇区后需要一段时间处理才可以继续读入下一个扇区
2,错位命名
具体做法:让相邻盘面的扇区编号“错位”。
原理:与“交替编号”的原理相同。“错位命名法”可降低延迟时间。
3,磁盘地址结构的设计
思考:为什么?
磁盘的物理地址是(柱面号,盘面号,扇区号)而不是(盘面号,柱面号,扇区号)。
答:读取地址连续的磁盘块时,采用(柱面号,盘面号,扇区号)的地址结构可以减少磁头移动消耗的时间。
5.3.4磁盘的管理
1,磁盘初始化
Step 1:进行低级格式化(物理格式化)
将磁盘的各个磁道划分为扇区。一个扇区通常可分为头、数据区域(如512B大小)、尾三个部分组成。管理扇区所需要的各种数据结构一般存放在头、尾两个部分,包括扇区校验码(如奇偶校验、CRC循环冗余校验码等,校验码用于校验扇区中的数据是否发生错误)。
Step2:将磁盘分区
每个分区由若干柱面组成(即分为我们熟悉的C盘、D盘、E盘)。
Step3:进行逻辑格式化
创建文件系统。包括创建文件系统的根目录、初始化存储空间管理所用的数据结构(如位示图、空闲分区表)。
2,引导块
计算机启动时需要运行初始化程序(自举程序)来完成初始化
ROM中存放很小的自举装入程序(不可更改)。
开机时计算机先运行“自举装入程序”找到引导块,并将完整的“自举程序”,通过执行该程序就可。
读入内存,完成初始化完整的自举程序存放在启动块(引导块)中,启动块位于磁盘的固定位置。
拥有启动分区的磁盘称为启动磁盘或系统磁盘(C:盘)。
3,环块的管理
坏了、无法正常使用的扇区就是“坏块”。这属于硬件故障,操作系统是无法修复的。应该将坏块标记出来,以免错误地使用到它。
简单的磁盘:
可以在逻辑格式化时(建立文件系统时)对整个磁盘进行坏块检查,标明哪些扇区是坏扇区,比如:在FAT表上标明。(在这种方式中,坏块对操作系统不透明)
复杂的磁盘:
磁盘控制器(磁盘设备内部的一个硬件部件)会维护一个坏块链表。
在磁盘出厂前进行低级格式化(物理格式化)时就将坏块链进行初始化。会保留一些“备用扇区”,用于替换坏块。这种方案称为扇区备用。且这种处理方式中,坏块对操作系统透明。
5.3.5固态硬盘SSD
1,原理
基于闪存技术Flash Memory,属于电可擦除ROM,即EEPROM(机械硬盘存储数据是通过盘面上的磁性物质,SSD是通过闪存技术)
2,组成
闪存翻译层:
负责翻译逻辑块号,找到对应页(Page)
存储介质:
多个闪存芯片(Flash Chip)
每个芯片包含多个块(block)
每个块包含多个页(page)
3,读写性能特性
以页(page)为单位读/写—相当于磁盘的“扇区”
以块(block)为单位“擦除”,擦干净的块,其中的每页都可以写一次,读无限次
支持随机访问,系统给定一个逻辑地址,闪存翻译层可通过电路迅速定位到对应的物理地址
读快、写慢。要写的页如果有数据,则不能写入,需要将块内其他页全部复制到一个新的(擦除过的)块中,再写入新的页
4,与机械硬盘相比的特点
SSD读写速度快,随机访问性能高,用电路控制访问位置;机械硬盘通过移动磁臂旋转磁盘控制访问位置,有寻道时间和旋转延迟。
SSD安静无噪音、耐摔抗震、能耗低、造价更贵
SSD的一个“块“被擦除次数过多(重复写同一个块)可能会坏掉,而机械硬盘的扇区不会因为写的次数太多而坏掉
5,磨损均衡技术
思想:
将“擦除“平均分布在各个块上,以提升使用寿命
动态磨损均衡
写入数据时,优先选择累计擦除次数少的新闪存块
静态磨损均衡
SSD监测并自动进行数据分配、迁移,让老旧的闪存块承担以读为主的储存任务,让较新的闪存块承担更多的写任务