概述
无论何时要放在一个大系统环境中去理解操作系统
计算机系统组成
计算机系统:硬件子系统 + 软件子系统
硬件:各种物理部件的有机组合,系统工作实体
软件:各种程序和文件,用于指挥计算机系统按指定要求协同工作
软硬件协同,硬件抽象为文件、外部shell
结构复杂的软件:工程化、社会计算性、文化性,考虑综合效益
用户视图
用户、程序员、语言处理程序设计者、操作系统设计者的视图是不同的,越往下能够看到和专注的地方越底层,分层思想
硬件系统
组成:中央处理器、主存、外围设备、总线
当今计算机硬件经典结构与主流组织方式:存储程序计算机。又称冯诺依曼计算机模型,现如今沿用的大得多还是该结构,由输入设备、存储器、控制器、运算器、输出设备五部分构成。
总线
总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是CPU、内存、输入输出设备传递息的公用通道
计算机的各个部件通过总线相连接,外围设备通过相应的接口电路再与总线相连接,从而形成了计算机硬件系统
总线类型
内部总线:CPU内部
系统总线:连接CPU、存储器和各种I/O模块主要部件
通信总线:用于计算机系统之间通信
系统总线实例:南桥、北桥。还挺意外的,原来所谓北桥就是主存控制器,南桥为I/O控制器
软件系统
组成:系统软件、支撑软件、应用软件
系统软件:操作系统、实用程序、语言处理程序、数据库管理系统
支撑软件:接口软件、工具软件、环境数据库,支持用户使用计算机的环境,提供开发工具,也可认为是系统软件的一部分
应用软件是用户按其需要自行编写的专用程序
操作技术发展
操作平台与操作系统
手工操作->装入程序引进->汇编语言引入->高级语言引入->简单批处理系统->操作系统与自动化操作
操作系统
OS是计算机系统最基础的系统软件,管理软硬件资源、控制程序执行,改善人机界面,合理组织计算机工作流程,为用户使用计算机提供良好运行环境。
OS是计算机系统的公共软件基础设施,所有应用程序共用OS服务,且OS内核是反应式reactive机制(中断驱动的)
操作系统组成:进程调度子系统、进程通信子系统…
操作系统类型:多道批处理操作系统、分时操作系统、实时操作系统
操作系统应用领域分类:服务器、并行、网络、手机、嵌入式…
计算无处不在,软件定义世界不过显然没有硬件加以匹配,这话也只能成为一句空话
资源管理视角
计算机系统资源:
硬件资源:处理器、内存、外设
信息资源:数据、程序
思考如何高效管理计算机的软硬件资源?
当底层的实现较为复杂时,显然就会有人帮我们做好抽象与屏蔽。驱动程序!
驱动程序:最底层的、直接控制和监视各类硬件资源的部分
资源的共享方式:
独占使用、并发使用
资源分配策略:
- 静态分配:进程运行前一次拿到全部独占资源,资源使用效率低
- 动态分配:使用资源前临时申请,可能产生竞争资源的死锁
- 资源抢占:被抢夺资源进程需要回滚
程序控制执行视角
由于CPU速度与I/O速度不匹配的矛盾非常突出,只有让多道程序同时进入内存争抢CPU运行,才可以够使得CPU和外围设备充分并行,从而提高计算机系统的使用效率
多道程序设计:让多个程序同时进入计算机的主存储器进行计算
多道程序设计的特点:
- CPU与外部设备充分并行
- 外部设备之间充分并行
- 发挥CPU的使用效率
- 提高单位时间的算题量
- 单道程序运算时间会增加
多道程序系统的实现:
- 为进入内存执行的程序建立管理实体:进程
- OS应能管理与控制进程程序的执行
- OS协调管理各类资源在进程间的使用
- 处理器的管理和调度
- 主存储器的管理和调度
- 其他资源的管理和调度
多道程序系统的实现要点:
- 如何使用资源:调用操作系统提供的服务例程(如何陷入操作系统)
- 如何复用CPU:调度程序(在CPU空闲时让其他程序运行)
- 如何使CPU与I/O设备充分并行:设备控制器与通道(专用的I/O处理器)
- 如何让正在运行的程序让出CPU:中断(中断正在执行的程序,引入OS处理)
操作控制计算机视角
计算机系统操作方式
- OS规定了合理操作计算机的工作流程
- OS的操作接口——系统程序
OS提供给用户的功能级接口,为用户提供的解决操作计算机和计算共性问题的所有服务的集合 - OS的两类作业级接口
- 脱机作业控制方式:作业控制语言
- 联机作业控制方式:操作控制命令
命令解释程序:接受和执行一条用户提出的对作业的加工处理命令,好像就是命令行交互式吧
人机交互视角
操作系统的人机交互部分
- OS改善人机界面,为用户使用计算机提供良好的环境
- 人机交互设备包括传统的终端设备和新型的模式识别设备
- OS的人机交互部分用于控制有关设备运行和理解执行设备传来的命令
- 人机交互功能是决定计算机系统友善性的重要因素,是当今OS研发热点
“人而不是技术是人机交互的中心”,代表性成果:鼠标、菜单与窗口控制
程序接口视角
操作系统的程序接口
- 操作系统的程序接口:操作系统为程序运行扩充的编程接口
- 系统调用:操作系统实现的完成某种特定功能的过程;为所有运行程序提供访问操作系统的接口
- POSIX支持
系统调用的实现机制
- 陷入处理机制:计算机系统中控制和实现系统调用的机制
- 陷入指令:也称访管指令,或异常中断指令,计算机系统为实现系统调用而引起处理器中断的指令
- 每个系统调用都事先规定了编号,并在约定寄存器中规定了传递给内部处理程序的参数
系统调用的实现要点
- 编写系统调用处理程序
- 设计一张系统调用入口地址表,每个入口地址指向一个系统调用的处理程序,并包含系统调用自带参数的个数
- 陷入处理机制需开辟现场保护区,以保存发生系统调用时的处理器现场
系统调用实现流程:
用户进程->系统调用功能号->进入内核->保护CPU现场->获取系统功能号、获取入口地址->系统调用处理子程序->结束处理、恢复现场
Linux系统调用执行流程:
应用程序->C库展开->中断处理->内核函数
系统结构视角
在计算机软件发展史上,OS是第一个大规模的软件系统
OS作为大型软件,结构设计是关键
操作系统软件的结构设计
- OS构件
内核、进程、线程、管程等 - 设计概念
模块化、层次式、虚拟化 - 内核设计是OS设计中最为复杂的部分
操作系统内核:
- 单内核:内核中各部件杂然混居的形态,始于1960年代,广泛使用;如Unix/Linux,及Windows(自称采用混合内核的CS结构)
- 微内核:1980年代始,强调结构性部件与功能性部件的分离,大部分OS研究都集中在此
- 混合内核:微内核和单内核的折中,较多组件在核心态中运行,以获得更快的执行速度
- 外内核:尽可能减少内核的软件抽象化和传统微内核的消息传递机制,使得开发者专注于硬件的抽象化;部分嵌入式系统使用
处理器管理
处理器与寄存器
用户程序可见寄存器:
- 可以使程序员减少访问主存储器的次数,提高指令执行的效率
- 所有程序可使用,包括应用程序和系统程序
- 数据寄存器:通用寄存器
- 地址寄存器:索引、栈指针、段地址等寄存器
控制与状态寄存器:
- 用于控制处理器的操作;主要被具有特权的操作系统程序使用,以控制程序的执行
- 程序计数器PC:存储将取指令的地址
- 指令寄存器IR:存储最近使用的指令
- 条件码CC:CPU为指令操作结果设置的位,标志正/负/零/溢出等结果
- 标志位:中断位、中断允许位、中断屏蔽位、处理器模式位、内存保护位…
指令与处理器模式
指令
机器指令:
- 机器指令是计算机系统执行的基本命令,是中央处理器执行的基本单位
- 指令由一个或多个字节组成,包括操作码字段、一个或多个操作数地址字段、以及一些表征机器状态的状态字以及特征码
- 指令完成各种算术逻辑运算、数据传输、控制流跳转
指令执行过程:
- CPU根据PC取出指令,放入IR,并对指令译码,然后发出各种控制命令,执行微操作系列,从而完成一条指令的执行
- 一种指令执行步骤如下:
- 取指:根据PC从存储器或高速缓冲存储器中取指令到IR
- 解码:解译IR中的指令来决定其执行行为
- 执行:连接到CPU部件,执行运算,产生结果并写回,同时在CC里设置运算结论标志;跳转指令操作PC,其他指令递增PC值
指令执行周期:包括取指、解码、执行过程
指令流水线:充分调度CPU
特权指令:只能被操作系统内核使用的指令
非特权指令:能够被所有程序使用的指令
处理器模式
处理器模式:
- 计算机通过设置处理器模式实现特权指令管理
- 计算机一般设置0、1、2、3等四种运行模式,建议分别对应:0操作系统内核、1系统调用、2共享库程序、3用户程序等保护级别
- 0模式可以执行全部指令;3模式只能执行非特权指令;其他每种运行模式可以规定执行的指令子集
- 一般来说,现代操作系统只使用0和3两种模式,对应于内核模式和用户模式
处理器模式切换:
- 包括“用户模式→内核模式”和“内核模式→用户模式”的转换
- 中断、异常或系统异常等事件导致用户程序向OS内核切换,触发:用户模式→内核模式
- 程序请求操作系统服务
- 程序运行时发生异常
- 程序运行时发生并响应中断
- OS内核处理完成后,调用中断返回指令(如Intel的iret)触发:内核模式→用户模式
中断与中断源
中断:中断是指程序执行过程中,遇到急需处理的事件时,暂时中止CPU上现行程序的运行,转去执行相应的事件处理程序,待处理完成后再返回原程序被中断处或调度其他程序执行的过程
操作系统是“中断驱动”的,换言之,中断是激活操作系统的唯一方式?此话何解,不过操作系统本身确实也是大型程序,在其上运行其他程序也必然需要中断吧。
中断、异常与系统异常:
- 狭义的中断指来源于处理器之外的中断事件,即与当前运行指令无关的中断事件,如I/O中断、时钟中断、外部信号中断等
- 异常指当前运行指令引起的中断事件,如地址异常、算术异常、处理器硬件故障等
- 系统异常指执行陷入指令而触发系统调用引起的中断事件,如请求设备、请求I/O、创建进程等
中断源:硬件故障中断事件、程序性中断事件、自愿性中断事件、I/O中断事件、外部中断事件
中断系统
中断系统是计算机系统中响应和处理中断的系统,包括硬件子系统和软件子系统两部分
中断响应由硬件子系统完成
中断处理由软件子系统完成
中断响应过程:
- 发现中断源,提出中断请求
- 发现中断寄存器中记录的中断
- 决定这些中断是否应该屏蔽
- 当有多个要响应的中断源时,根据规定的优先级选择一个
- 中断当前程序的执行
- 保存当前程序的PSW/PC到核心栈
- 转向操作系统的中断处理程序
中断的处理:
- 中断处理程序
操作系统处理中断事件的控制程序, 主要任务是处理中断事 件和恢复正常操作 - 中断处理过程
- 保护未被硬件保护的处理器状态
- 通过分析被中断进程的PSW中断码字段,识别中断源
- 分别处理发生的中断事件
- 恢复正常操作
多中断响应与处理
中断屏蔽:当计算机检测到中断时, 中断装置通过中断屏蔽位决定是否响应已发生的中断,从而进行有选择的响应中断
中断优先级:当计算机同时检测到多个中断时, 中断装置响应中断的顺序,不同类型操作系统有不同中断优先级
中断嵌套处理:当计算机响应中断后,在中断处理过程中,可以再响应其他中断
多中断的响应与处理:
- 决定中断处理次序的因素:
- 中断屏蔽可以使中断装置不响应某些中断
- 中断优先级决定了中断装置响应中断的次序
- 中断可以嵌套处理, 但嵌套的层数应有限制
- 中断的嵌套处理改变了中断处理的次序
进程及其状态
操作系统必须全方位地管理计算机系统中运行的程序,因此,操作系统为正在运行程序建立管理实体——进程
进程的概念:
- 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动
- 进程是操作系统进行资源分配和调度的一个独立单位
一个进程包括五个实体部分,分别是:
- (OS管理运行程序的)数据结构P
- (运行程序的)内存代码C
- (运行程序的)内存数据D
- (运行程序的)通用寄存器信息R
- (OS控制程序执行的)程序状态字信息PSW
进程举例1:
- 不同程序在不同数据集上运行:构成两个无关进程
- 不同程序在相同数据集上运行:构成两个共享数据的交往进程
- 相同代码在不同数据集上运行:构成两个共享代码的无关进程
前述的程序与数据集均是内存级的
进程举例2:
- 在不同时段中针对(同一个外存数据文件)运行(同一个外存程序文件),意味着完全不同的(P, C, D, R, Psw)
- 所以两次运行构成两个不同的进程
概念级的进程状态:
- 运行态指进程占有处理器运行
- 就绪态指进程具备运行条件等待处理器运行
- 等待态指进程由于等待资源、输入输出、信号等而不具备运行条件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjOwp42z-1687783975768)(null)]
重点理解三态模型
进程挂起:
OS无法预期进程的数目与资源需求,计算机系统在运行过程中可能出现资源不足的情况。
解决办法:剥夺某些进程的内存及其他资源,调入OS管理的对换区,不参加进程调度,待适当时候再调入内存、恢复资源、参与运行。这就是进程挂起。
挂起态与等待态有着本质区别,后者占有已申请到的资源处于等待,前者没有任何资源。
进程挂起的选择与恢复:
- 一般选择等待态进程进入挂起等待态
- 也可选择就绪态进程进入挂起就绪态
- 运行态进程还可以挂起自己
- 等待事件结束后,挂起等待态进入挂起就绪态
- 一般选择挂起就绪态进程予以恢复
进程数据描述
PCB
进程控制块(PCB):
- 进程控制块PCB是OS用于记录和刻画进程状态及环境信息的数据结构,包括标志信息、现场信息、控制信息
- 借助PCB,OS可以全面管理进程的物理实体,刻画进程的执行现状,控制进程的执行
标志信息
用于存放唯一标识该进程的信息:
- 系统分配的标识号
- 系统分配的进程组标识号
- 用户定义的进程名
- 用户定义的进程组名
现场信息
用于存放该进程运行时的处理器现场信息
- 用户可见寄存器内容:数据寄存器、地址寄存器
- 控制与状态寄存器内容:PC、IR、PSW
- 栈指针内容:核心栈与用户栈指针
控制信息
用于存放与管理、调度进程相关的信息
- 调度相关信息:状态、等待事件/原因、优先级
- 进程组成信息:代码/数据地址、外存映像地址
- 队列指引元:进程队列指针、父子兄弟进程指针
- 通信相关信息:消息队列、信号量、锁
- 进程特权信息:如内存访问权限、处理器特权
- 处理器使用信息:占用的处理器、时间片、处理器使用时间/已执行总时间、记账信息
- 资源清单信息:如正占有的资源、已使用的资源
进程映像
某一时刻进程的内容及其执行状态集合:
- 进程控制块: 保存进程的标识信息、状态信息和控制信息
- 进程程序块: 进程执行的程序空间
- 进程数据块: 进程处理的数据空间,包括数据、处理函数的用户栈和可修改的程序
- 核心栈: 进程在内核模式下运行时使用的堆栈,中断或系统过程使用
进程映像是内存级的物理实体,又称为进程的内存映像
进程上下文
- 进程的执行需要环境支持,包括CPU现场和Cache中的执行信息
- OS中的进程物理实体和支持进程运行的环境合成进程上下文,包括以下:
- 用户级上下文:用户程序块/用户数据区/用户栈/用户共享内存
- 寄存器上下文:PSW/栈指针/通用寄存器
- 系统级上下文:PCB/内存区表/核心栈
- 进程上下文刻画了进程的执行情况
用户理解的上下文:虚存(程序、数据、用户栈)+ 处理机现场
系统理解的上下文:虚存(程序、数据、用户栈)+ 处理机现场 + PCB
进程管理实现
概念级的OS进程管理软件
- 关键的进程管理软件包括:
- 系统调用/中断/异常处理程序
- 队列管理模块
- 进程控制程序
- 进程调度程序(独立进程居多)
- 进程通信程序(多个程序包)
- 终端登录与作业控制程序、性能监控程序、审计程序等外围程序
队列管理模块
- 队列管理模块是操作系统实现进程管理的核心模块
- 操作系统建立多个进程队列,包括就绪队列和等待队列
- 按需组织为先进先出队列与优先队列
- 队列中的进程可以通过PCB中的队列指引元采用单/双指引元或索引连接
- 出队和入队操作
- 进程与资源调度围绕进程队列展开
进程的控制与管理
- 进程创建:进程表加一项,申请PCB并初始化,生成标识,建立映像,分配资源,移入就绪队列
- 进程撤销:从队列中移除,归还资源,撤销标识,回收PCB,移除进程表项
- 进程阻塞:保存现场信息,修改PCB,移入等待队列,调度其他进程执行
- 进程唤醒:等待队列中移出,修改PCB,移入就绪队列(该进程优先级高于运行进程触发抢占)
- 进程挂起:修改状态并出入相关队列,收回内存等资源送至对换区
- 进程激活:分配内存,修改状态并出入相关队列
- 其他:如修改进程特权
原语与进程控制原语
- 进程控制过程中涉及对OS核心数据结构(进程表/PCB池/队列/资源表)的修改
- 为防止与时间有关的错误,应使用原语
- 原语是由若干条指令构成的完成某种特定功能的程序,执行上具有不可分割性
- 原语的执行可以通过关中断实现
- 进程控制使用的原语称为进程控制原语
- 另一类常用原语是进程通信原语
进程切换
- 进程切换指从正在运行的进程中收回处理器,让待运行进程来占有处理器运行
- 进程切换实质上就是被中断运行进程与待运行进程的上下文切换,处理过程是:
- 保存被中断进程的上下文
- 转向进程调度
- 恢复待运行进程的上下文
模式切换
- 进程切换必须在操作系统内核模式下完成,这就需要模式切换
- 模式切换又称处理器状态切换,包括:
- 用户模式到内核模式,由中断/异常/系统调用中断用户进程执行而触发
- 内核模式到用户模式,OS执行中断返回指令将控制权交还用户进程而触发
模式切换的基本工作任务
中断装置完成正向模式切换,包括:
- 处理器模式转为内核模式
- 保存当前进程的PC/PSW值到核心栈
- 转向中断/异常/系统调用处理程序
中断返回指令完成逆向模式转换,包括:
- 从待运行进程核心栈中弹出PSW/PC值
- 处理器模式转为用户模式
进程切换的发生时机
进程切换一定发生在中断/异常/系统调用处理过程中,常见的情况是:
- 阻塞式系统调用、虚拟地址异常导致被中断进程进入等待态
- 时间片中断、I/O中断后发现更高优先级进程导致被中断进程转入就绪态
- 终止用系统调用、不能继续执行的异常导致被中断进程进入终止态
一些中断/异常不会引起进程状态转换,不会引起进程切换,只是在处理完成后把控制权交回给被中断进程
多线程环境
传统进程是单线程结构进程
问题
单线程结构进程的问题:
单线程结构进程在并发程序设计上存在的问题
- 进程切换开销大
- 进程通信开销大
- 限制了进程并发的粒度
- 降低了并行计算的效率
解决思路
- 把进程的两项功能,即“独立分配资源”与“被调度分派执行”分离开来
- 进程作为系统资源分配和保护的独立单位,不需要频繁地切换;
- 线程作为系统调度和分派的基本单位,能轻装运行,会被频繁地调度和切换
- 线程的出现会减少进程并发执行所付出的时空开销,使得并发粒度更细、并发性更好
多线程环境下进程概念
在多线程环境中,进程是操作系统中进行保护和资源分配的独立单位。具有:
- 用来容纳进程映像的虚拟地址空间
- 对进程、文件和设备的存取保护机制
多线程环境下线程概念
线程是进程的一条执行路径,是调度的基本单位,同一个进程中的所有线程共享进程获得的主存空间和资源。它具有:
- 线程执行状态
- 受保护的线程上下文,当线程不运行时,用于存储现场信息
- 独立的程序指令计数器
- 执行堆栈
- 容纳局部变量的静态存储器
多线程环境下线程的状态与调度
线程状态有运行、就绪和睡眠,无挂起
OS感知线程环境下:
- 处理器调度对象是线程
- 进程没有三状态(或者说只有挂起状态)
OS不感知线程环境下:
- 处理器调度对象仍是进程
- 用户空间中的用户调度程序调度线程
并发多线程程序设计的优点
- 快速线程切换
- 减少(系统)管理开销
-(线程)通信易于实现 - 并行程度提高
- 节省内存空间
多线程技术应用
- 前台和后台工作
- C/S应用模式
- 加快执行速度
- 设计用户接口
KLT和ULT
KLT
KLT内核级线程:
- 线程管理的所有工作由OS内核来做
- OS提供了一个应用程序设计接口API,供开发者使用KLT
- OS直接调度KLT
KLT特点:
- 进程中的一个线程被阻塞了,内核能调度同一进程的其它线程占有处理器运行
- 多处理器环境中,内核能同时调度同一进程中多个线程并行执行
- 内核自身也可用多线程技术实现,能提高操作系统的执行速度和效率
- 应用程序线程在用户态运行,线程调度和管理在内核实现,在同一进程中,控制权从一个线程传送到另一个线程时需要模式切换,系统开销较大
ULT
ULT用户级线程:
- 用户空间运行的线程库,提供多线程应用程序的开发和运行支撑环境
- 任何应用程序均需通过线程库进行程序设计,再与线程库连接后运行
- 线程管理的所有工作都由应用程序完成,内核没有意识到线程的存在
ULT特点:
- 所有线程管理数据结构均在进程的用户空间中,线程切换不需要内核模式,能节省模式切换开销和内核的宝贵资源
- 允许进程按应用特定需要选择调度算法,甚至根据应用需求裁剪调度算法
- 能运行在任何OS上,内核在支持ULT方面不需要做任何工作
- 不能利用多处理器的优点,OS调度进程,仅有一个ULT能执行
- 一个ULT的阻塞,将引起整个进程的阻塞
Jacketing技术
- 把阻塞式系统调用改造成非阻塞式的
- 当线程陷入系统调用时,执行jacketing程序
- 由jacketing 程序来检查资源使用情况,以决定是否执行进程切换或传递控制权给另一个线程
用户级线程vs内核级线程
用户级线程:线程调度->进程调度->处理,适用于逻辑并行性问题
内核级线程:线程调度->处理,适用于物理并行性问题
多线程实现的混合式策略
混合式策略:
- 线程创建是完全在用户空间做的
- 单应用的多个ULT可以映射成一些KLT,通过调整KLT数目,可以达到较好的并行效果
混合式特点:
- 组合用户级线程/内核级线程设施
- 线程创建完全在用户空间中完成,线程的调度和同步也在应用程序中进行
- 一个应用中的多个用户级线程被映射到一些(小于等于用户级线程数目)内核级线程上
- 程序员可以针对特定应用和机器调节内核级线程的数目,以达到整体最佳结果
- 该方法将会结合纯粹用户级线程方法和内核级线程方法的优点,同时减少它们的缺点
线程混合式策略下的线程状态:
- KLT三态,系统调度负责
- ULT三态,用户调度负责
- 活跃态ULT代表绑定KLT的三态?
- 活跃态ULT运行时可激活用户调度
- 非阻塞系统调用可使用Jacketing启动用户调度,调整活跃态ULT
处理器调度层次
调度层次
高级调度:又称长程调度,作业调度
- 决定能否加入到执行的进程池中
中级调度,又称平衡负载调度
- 决定主存中的可用进程集合
低级调度:又称短程调度,进程调度
- 决定哪个可用进程占用处理器执行
处理器调度层次与进程状态转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c3lt90cZ-1687783975697)(null)]
高级调度
- 分时OS中,高级调度决定:
- 是否接受一个终端用户的连接
- 命令能否被系统接纳并构成进程
- 新建态进程是否加入就绪进程队列
- 批处理OS中,高级调度又称为作业调度,功能是按照某种原则从后备作业队列中选取作业进入主存,并为作业做好运行前的准备工作和完成后的善后工作
中级调度
- 引进中级调度是为了提高内存利用率和作业吞吐量
- 中级调度决定那些进程被允许驻留在主存中参与竞争处理器及其他资源,起到短期调整系统负荷的作用
- 中级调度把一些进程换出主存,从而使之进入“挂起”状态,不参与进程调度,以平顺系统的负载
低级调度
- 低级调度:又称处理器调度、进程调度、短程调度,按照某种原则把处理器分配给就绪态进程或内核级线程
- 进程调度程序:又称分派程序,操作系统中实现处理器调度的程序,是操作系统的最核心部分
- 处理器调度策略的优劣直接影响到整个系统的性能
低级调度的主要功能
- 记住进程或内核级线程的状态
- 决定某个进程或内核级线程什么时候获得处理器,以及占用多长时间
- 把处理器分配给进程或内核级线程
- 收回处理器
处理器调度算法
选择处理器调度算法的原则:
资源利用率、响应时间、周转时间、吞吐量、公平性(基本不能同时满足,基本都有取舍)
优先数调度算法
- 根据分配给进程的优先数决定运行进程
- 抢占式优先数调度算法
- 非抢占式优先数调度算法
- 优先数的确定准则
- 进程负担任务的紧迫程度
- 进程的交互性
- 进程使用外设的频度
- 进程进入系统的时间长短
- 与进入系统时间相关的优先数
- 计算时间短(作业/进程)优先
- 剩余计算时间短进程优先
- 响应比高者(作业/进程)优先
- 响应比 = 等待时间/进入时间
- 先来先服务:先进队先被选择
- 多用于高级调度;低级调度中,以计算为主的进程过于优越
时间片轮转调度算法
- 根据各个进程进入就绪队列的时间先后轮流占有CPU一个时间片
- 时间片中断
- 时间片的确定:选择长短合适的时间片, 过长则退化为先来先服务算法, 过短则调度开销大
- 单时间片,多时间片和动态时间片
分级调度算法
又称多队列策略,反馈循环队列
基本思想:
- 建立多个不同优先级的就绪进程队列
- 多个就绪进程队列间按照优先数调度
- 高优先级就绪进程,分配的时间片短
- 单个就绪进程队列中进程的优先数和时间片相同
给高优先级分配更短的时间片?为什么?因为优先级高的通常是短作业?貌似确实解释的通。
分级原则:
- 一般分级原则
- 外设访问,交互性,时间紧迫程度,系统效率,用户立场…(用户立场可还行)
- 现代操作系统的实现模型
- 多个高优先级的实时进程队列,如:硬实时、网络、软实时
- 多个分时任务的进程队列,根据基准优先数和执行行为调整
- 队列数可能多达32-128个
彩票调度算法
基本思想:为进程发放针对系统各种资源(如CPU时间)的彩票;当调度程序需要做出决策时,随机选择一张彩票,持有该彩票的进程将获得系统资源
赌狗算法?
合作进程之间可以进行彩票交换
存储管理
存储管理主要模式
逻辑地址
逻辑地址:相对地址,用户编程序所使用的地址空间。经过之前的学习可知,操作系统引入保护模式,从而诞生了逻辑地址
逻辑地址从0开始编号,有两种形式:
- 一维逻辑地址(地址)
- 二维逻辑地址(段号:段内地址)
段式程序设计
- 把一个程序设计成多个段
- 代码段、数据段、堆栈段、等等
- 用户可以自己应用段覆盖技术扩充内存空间使用量
- 这一技术是程序设计技术,不是OS存储管理的功能
物理地址
物理地址:绝对地址,即程序执行所使用的地址空间
处理器执行指令时按照物理地址进行
主存储器复用
- 多道程序设计需要复用主存
- 按照分区复用:
- 主存划分为多个固定/可变尺寸的分区
- 一个程序/程序段占用一个分区
- 按照页架复用:
- 主存划分成多个固定大小的页架
- 一个程序/程序段占用多个页架
存储管理的基本模式
- 单连续存储管理:一维逻辑地址空间的程序占用一个主存固定分区或可变分区
- 段式存储管理:段式二维逻辑地址空间的程序占用多个主存可变分区
- 页式存储管理:一维逻辑地址空间的程序占用多个主存页架区
- 段页式存储管理:段式二维逻辑地址空间的程序占用多个主存页架区
存储管理的功能
地址转换
- 地址转换:又称重定位,即把逻辑地址转换成绝对地址
- 静态重定位:在程序装入内存时进行地址转换
- 由装入程序执行,早期小型OS使用
- 动态重定位:在CPU执行程序时进行地址转换
- 从效率出发,依赖硬件地址转换机构
主存储空间的分配与去配
- 分配:进程装入主存时,存储管理软件进行具体的主存分配操作,并设置一个表格记录主存空间的分配情况
- 去配:当某个进程撤离或主动归还主存资源时,存储管理软件要收回它所占用的全部或者部分存储空间,调整主存分配表信息
主存储器空间的共享
- 多个进程共享主存储器资源:多道程序设计技术使若干个程序同时进入主存储器,各自占用一定数量的存储空间,共同使用一个主存储器
- 多个进程共享主存储器的某些区域:若干个协作进程有共同的主存程序块或者主存数据块
存储保护
- 为避免主存中的多个进程相互干扰,必须对主存中的程序和数据进行保护
- 私有主存区中的信息:可读可写
- 公共区中的共享信息:根据授权
- 非本进程信息:不可读写
- 这一功能需要软硬件协同完成
- CPU检查是否允许访问,不允许则产生地址保护异常,由OS进行相应处理
主存储器空间的扩充
- 存储扩充:把磁盘作为主存扩充,只把部分进程或进程的部分内容装入内存
- 1.对换技术:把部分不运行的进程调出
- 2.虚拟技术:只调入进程的部分内容
- 这一工作需要软硬件协作完成
- 1.对换进程决定对换,硬件机构调入
- 2.CPU处理到不在主存的地址,发出虚拟地址异常,OS将其调入,重执指令
虚拟存储技术如今身边就可以看到广泛应用,如手机内存。
虚拟存储器
虚拟存储器思想的提出:
- 主存容量限制带来诸多不便
- 用户编写程序必须考虑主存容量限制
- 多道程序设计的道数受到限制
- 用户编程行为分析
- 全面考虑各种情况,执行时有互斥性
- 顺序性和循环性等空间局部性行为
- 某一阶段执行的时间局部性行为
- 因此可以考虑部分调入进程内容
虚拟存储器的实现思路:
- 需要建立与自动管理两个地址空间
- (辅存)虚拟地址空间:容纳进程装入
- (主存)实际地址空间:承载进程执行
- 对于用户,计算机系统具有一个容量大得多的主存空间,即虚拟存储器
- 虚拟存储器是一种地址空间扩展技术,通常意义上对用户编程透明
存储管理的硬件支撑
大多为机组内容,甚至比机组简单很多
Cache
- Cache是介于CPU和主存储器间的高速小容量存储器,由静态存储芯片SRAM组成,容量较小但比主存DRAM技术更加昂贵而快速, 接近于CPU的速度
- CPU往往需要重复读取同样的数据块,Cache的引入与缓存容量的增大,可以大幅提升CPU内部读取数据的命中率,从而提高系统性能
- 由于CPU芯片面积和成本,Cache很小
- 根据成本控制,划分为L1、L2、L3三级
地址转换/存储保护的硬件支撑
给出逻辑地址,根据选择子选择GDT还是LDT方式对应去查询物理地址,总之就是基地址+偏移量
- 鉴于程序执行与数据访问的局部性原理,存储管理软件使用Cache可以大幅度提升程序执行效率
- 动态重定位、存储保护等,若无硬件支撑在效率上是无意义的,即无实现价值
- 无虚拟地址中断,虚拟存储器无法实现
- 无页面替换等硬件支撑机制,虚拟存储器在效率上是无意义的
软硬件协同的重要性!!!
单连续分区存储管理
每个进程占用一个物理上完全连续的存储空间
单用户连续分区存储管理
- 主存区域划分为系统区与用户区
- 设置一个栅栏寄存器界分两个区域,硬件用它在执行时进行存储保护
- 一般采用静态重定位进行地址转换
- 硬件实现代价低
- 适用于单用户单任务操作系统,如DOS
静态重定位:在装入一个作业时,把该作业中程序的指令地址和数据地址全部转换成绝对地址
固定分区存储管理
基本思想:
- 支持多个分区,当然分区有大有小
- 分区数量固定
- 分区大小固定
- 可用静态重定位
- 硬件实现代价低
- 早期OS采用
主存分配表,固定
可变分区存储管理
- 固定分区存储管理不够灵活,既不适应大尺寸程序,又存在内存内零头,有浪费
- 能否按照进程实际内存需求动态划分分区,并允许分区个数可变
- 这就是可变分区存储管理
- 创建一个进程时,根据进程所需主存量查看主存中是否有足够的空闲空间
- 若有,则按需要量分割一个分区
- 若无,则令该进程等待主存资源
- 由于分区大小不定,分区个数也是不定的
主存分配表分为已分配区表与未分配区表,采用链表
可变分区方式的内存零头
- 固定分区方式会产生内存内零头
- 可变分区方式也会随着进程的内存分配产生一些小的不可用的内存分区,称为内存外零头
- 最优适配算法最容易产生外零头
- 任何适配算法都不能避免产生外零头
移动技术(程序浮动技术)
- 移动进程以填补空闲区,解决内存外零头
- 需要动态重定位支撑
页式存储管理
基本原理
- 分页存储器将主存划分成多个大小相等的页架
- 受页架尺寸限制,程序的逻辑地址也自然分成页
- 不同的页可以放在不同页架中,不需要连续
- 页表用于维系进程的主存完整性
页式存储管理中的地址
页式存储管理的逻辑地址由两部分组成,页号和单元号
页式存储管理的物理地址也有两部分组成:页架号和单元号
地址转换可以通过查页表完成
内存分配/去配:
可以用一张位示图来记录主存分配情况0/1
建立进程页表维护主存逻辑完整性
页的共享
- 页式存储管理能够实现多个进程共享程序和数据
- 数据共享:不同进程可以使用不同页号共享数据页
- 程序共享:不同进程必须使用相同页号共享代码页
- 共享代码页中的(JMP <页内地址>)指令,使用不同页号是做不到
页式存储地址转换代价:
- 页表放在主存: 每次地址转换必须访问两次主存
- 1.按页号读出页表中的相应页架号
- 2.按计算出来的绝对地址进行读写
- 存在问题:降低了存取速度
- 解决办法:利用Cache存放部分页表->快表!
快表
- 为提高地址转换速度,设置一个专用的高速存储器,用来存放页表的一部分
- 快表:存放在高速存储器中的页表部分
- 快表表项:页号,页架号
- 这种高速存储器是联想存储器,即按照内容寻址,而非按照地址访问
引入快表可加快地址转换速度,计组我怎么记得是数据的拿取使用更快了?不过好像意思差不多?存有疑问
基于快表的地址转换流程:
- 按逻辑地址中的页号查快表
- 若该页已在快表中,则由页架号和单元号形成绝对地址
- 若该页不在快表中,则再查主存页表形成绝对地址,同时将该页登记到快表中
- 当快表填满后,又要登记新页时,则需在快表中按一定策略淘汰一个旧登记项
多道程序环境下的进程表:
- 进程表中登记了每个进程的页表
- 进程占有处理器运行时,其页表起始地址和长度送入页表控制寄存器
页式虚拟存储管理
- 把进程全部页面装入虚拟存储器,执行时先把部分页面装入实际内存,然后,根据执行行为,动态调入不在主存的页,同时进行必要的页面调出
- 现代OS的主流存储管理技术
- 首次只把进程第一页信息装入主存,称为请求页式存储管理
页式虚拟存储管理的页表
- 需要扩充页表项,指出:
- 每页的虚拟地址、实际地址
- 主存驻留标志、写回标志、保护标志、引用标志、可移动标志
页式虚拟存储管理的实现
- CPU处理地址
- 若页驻留,则获得块号形成绝对地址
- 若页不在内存,则CPU发出缺页中断
- OS处理缺页中断
- 若有空闲页架,则根据辅存地址调入页,更新页表与快表等
- 若无空闲页架,则决定淘汰页,调出已修改页,调入页,更新页表与快表
页面调度算法
主存空间已满而又需要装入新页时,页式虚拟存储管理必须按照一定的算法把已在主存的一些页调出去选择淘汰页的工作称为页面调度,选择淘汰页的算法称为页面调度算法。
缺页中断率:f=F/(S+F),缺页中断率是衡量存储管理性能和用户编程水平的重要依据
影响缺页中断率的因素:
- 分配给进程的页架数:可用页架数越多,则缺页中断率就越低
- 页面的大小:页面尺寸越大,则缺页中断率就越低
- 用户的程序编制方法:在大数据量情况下,对缺页中断率也有很大影响
OPT页面调度算法
- 理想的调度算法是:当要调入新页面时,首先淘汰以后不再访问的页,然后选择距现在最长时间后再访问的页
- 该算法由Belady提出,称Belady算法,又称最佳算法(OPT)
- OPT只可模拟,不可实现
搞不懂这算法意义何在,不过如果CPU预测能力够强的话,指导意义也挺高?
先进先出FIFO页面调度算法
- 总是淘汰最先调入主存的那一页,或者说主存驻留时间最长的那一页(常驻的除外)
- 模拟的是程序执行的顺序性,有一定合理性
最近最少用LRU页面调度算法
- 淘汰最近一段时间较久未被访问的那一页,即那些刚被使用过的页面,可能马上还要被使用到
- 模拟了程序执行的局部属性,既考虑了循环性又兼顾了顺序性
- 严格实现的代价大(需要维持特殊队列)
最不常用LFU页面调度算法
- 淘汰最近一段时间内访问次数较少的页面,对OPT的模拟性比LRU更好
- 基于时间间隔中断,并给每一页设置一个计数器
- 时间间隔中断发生后,所有计数器清0
- 每访问页1次就给计数器加1
- 选择计数值最小的页面淘汰
时钟CLOCK页面调度算法
- 采用循环队列机制构造页面队列,形成了一个类似于钟表面的环形表
- 队列指针则相当于钟表面上的表针,指向可能要淘汰的页面
- 使用页引用标志位
CLOCK算法的工作流程
- 页面调入主存时,其引用标志位置1
- 访问主存页面时,其引用标志位置1
- 淘汰页面时,从指针当前指向的页面开始扫描循环队列
- 把所遇到的引用标志位是1的页面的引用标志位清0,并跳过
- 把所遇到的引用标志位是0的页面淘汰,指针推进一步
反置页表
反置页表的提出:
- 页表及相关硬件机制在地址转换、存储保护、虚拟地址访问中发挥了关键作用
- 为页式存储管理设置专门硬件机构
- 内存管理单元MMU:CPU管理虚拟/物理存储器的控制线路,把虚拟地址映射为物理地址,并提供存储保护,必要时确定淘汰页面
- 反置页表IPT:MMU用的数据结构
设计思想:
- 针对内存中的每个页架建立一个页表,按照块号排序
- 表项包含:正在访问该页框的进程标识、页号及特征位,和哈希链指针等
- 用来完成内存页架到访问进程页号的对应,即物理地址到逻辑地址的转换
反置页表的页表项:
- 页号:虚拟地址页号
- 进程标志符:使用该页的进程号(页号和进程标志符结合起来标志一个特定进程的虚拟地址空间的一页)
- 标志位:有效、引用、修改、保护和锁定等标志信息
- 链指针:哈希链
基于反置页表的地址转换过程
- MMU通过哈希表把进程标识和虚页号转换成一个哈希值,指向IPT的一个表目
- MMU遍历哈希链找到所需进程的虚页号,该项的索引就是页架号,通过拼接位移便可生成物理地址
- 若遍历整个反置页表中未能找到匹配页表项,说明该页不在内存,产生缺页中断,请求操作系统调入
淘汰页面的操作同样由MMU完成
段式存储管理
段式程序设计:
- 每个程序可由若干段组成,每一段都可以从“0”开始编址,段内的地址是连续的
- 分段存储器的逻辑地址由两部分组成,段号:单元号
段式存储管理的基本思想:
- 段式存储管理基于可变分区存储管理实现,一个进程要占用多个分区
- 硬件需要增加一组用户可见的段地址寄存器(代码段、数据段、堆栈段,附加段),供地址转换使用
- 存储管理需要增加设置一个段表,每个段占用一个段表项,包括:段始址、段限长,以及存储保护、可移动、可扩充等标志位
段的共享:
- 通过不同进程段表中的项指向同一个段基址来实现
- 对共享段的信息必须进行保护,如规定只能读出不能写入,不满足保护条件则产生保护中断
段式虚拟存储
- 把进程的所有分段都存放在辅存中,进程运行时先把当前需要的一段或几段装入主存,在执行过程中访问到不在主存的段时再把它们动态装入
- 段式虚拟存储管理中段的调进调出是由OS自动实现的,对用户透明
- 与段覆盖技术不同,它是用户控制的主存扩充技术,OS不感知
段式虚拟存储管理的段表扩充:
扩充包括特征位、存取权限、扩充位、标志位
段页式存储管理
段页式存储管理的基本思想:
- 段式存储管理可以基于页式存储管理实现
- 每一段不必占据连续的存储空间,可存放在不连续的主存页架中
- 能够扩充为段页式虚拟存储管理
- 装入部分段,或者装入段中部分页面
我说这里怎么好像跟我机组学的不太对劲?原来是我自己把两个概念搞混了。将cache映射策略中直接映射、关联映射、组关联映射
的概念同这里混淆了。
设备管理
设备管理基础
I/O设备:输入输出设备、外围设备、外部设备
设备管理目标:
解决设备和CPU速度的不匹配,使主机和设备充分并行工作,提高设备使用效率
设备管理目标:
- 设置中断处理
- 缓冲区管理
- 设备的分配和去配
- 设备驱动调度
- 虚拟设备的实现
设备管理实现层次:
I/O硬件
I/O软件
I/O控制方式
设备控制器:为达到模块化和通用性的设计目标,通常分开设置设备的机械部件和电子部件
设备控制器的功能:
设备控制器是CPU与设备之间的接口,接收和识别CPU或通道发来的命令;实现数据交换;发现和记录设备及自身的状态信息,供CPU处理时使用;当连接多台设备时,识别设备地址
I/O控制的轮询方式:
- 处理器向控制器发送I/O命令,轮询I/O结果
- 若设备未就绪,则重复测试过程,直至设备就绪
- 执行内存数据交换
- 等待I/O操作完成后,处理器才可以继续其他操作
I/O控制的中断方式:
- 处理器向控制器发出具体I/O命令,然后继续执行后续指令
- 若进程支持异步I/O,后续指令仍可是该进程中的指令
- 否则,该进程在这个中断上挂起,处理器执行其他工作
- 控制器检查设备状态,就绪后发出中断
- CPU响应中断,进行中断处理
- 中断处理执行内存数据交换
I/O控制的DMA方式:
直接存储器访问、DMA模块能够代替处理器来控制主存和设备管理器的数据交换
DMA的工作流程:
- 处理器向DMA模块发出I/O命令
- 处理器继续执行其他工作,DMA模块负责传送全部数据
- 数据传送结束后,DMA中断处理器
I/O控制方式的总结:
- 轮询方式:CPU等待设备就绪,且参与内存数据交换
- 中断方式:CPU无需等待设备就绪,响应中断后参与内存数据交换
- DMA方式:CPU只在I/O开始和结束时参与,不参与主存数据交换
I/O通道:
- 又称为通道控制器、I/O处理器,用于完成逻辑上独立的I/O任务
- 采用四级连接:处理器、通道、控制器、设备
- 通道可控制多台同类或不同类的设备
- 处理器不再执行I/O指令,而是在主存中组织通道程序,由I/O通道执行
CPU与通道高度并行工作
总线与I/O
总线:解决I/O速度不匹配问题,I/O和CPU速度、各设备I/O速度不匹配,使主机和设备充分并行,提高系统效率
单总线模型:
将CPU、主存和I/O模块连接到同一总线
优点:结构简单,易于扩充
缺点:共用总线;设备多时总线压力大,传输时延长,且慢速外设占用带宽多
三级总线模型:
主存和Cache通过主存总线连接,主存总线和扩展总线上的I/O设备间通过扩展总线接口缓冲
优点:主存与I/O之间的数据传送、处理器的内存活动分离;可以支持更多的I/O设备
缺点:不适用于I/O设备数据速率相差太大的情形
南桥与北桥:
通过存储总线、PCI总线、E(ISA)总线分别连接主存、高速I/O设备和低速I/O设备
优点:可以支持不同数据速率的I/O设备
一种基于通道的服务器总线模型:
支持CPU、主存和多个I/O通道之间的数据传送
支持I/O通道和I/O控制器,以及I/O控制器和设备之间的数据传送
I/O软件实现层次
I/O软件的设计目标:
高效率:改善设备效率,尤其是磁盘I/O操作的效率
通用性:用统一标准来管理所有设备
设计思路:
把软件组织成层次结构,低层软件用来屏蔽硬件细节,高层软件向用户提供简洁、友善、统一的界面
I/O软件设计考虑问题:设备无关性、出错处理、同步/异步传输、缓冲技术
I/O软件实现
I/O中断处理程序:位于OS底层,与硬件设备密切相关,与系统其余部分尽可能少地发生联系
进程请求I/O操作时,通常被阻塞
数据传输结束后产生I/O中断
CPU响应请求并转入中断处理程序
功能:检查设备状态寄存器,判断中断原因,根据I/O操作完成情况进行相应处理
每个设备驱动程序原则只处理一种设备,或者一类紧密相关的设备
I/O缓冲
设置I/O缓冲的目的:
- 解决CPU与设备之间速度不匹配的矛盾
- 协调逻辑记录大小和物理记录大小不一致的问题
- 提高CPU和设备的并行性
- 减少I/O操作对CPU的中断次数
- 放宽对CPU中断响应时间的要求
I/O缓冲区:
I/O缓冲区:在内存中开辟的存储区,专门用于临时存放I/O操作的数据,读操作、写操作
单缓冲技术、双缓冲技术、循环缓冲技术,继续调节设备和进程速度不匹配的问题
设备独立性
设备独立性:用户通常不指定物理设备,而是指定逻辑设备,使得用户进程和物理设备分离开来,再通过其它途径建立逻辑设备和物理设备之间的映射
设备管理中需要将逻辑设备名转换为物理设备名,为此系统需要提供逻辑设备名和物理设备名的对应表以供转换使用
设备独立性优点:
- 应用程序与具体物理设备无关,系统增减或变更设备时不需要修改源程序
- 易于应对各种I/O设备故障,提高系统的可靠性
- 增加设备分配的灵活性,有利于更加有效地利用设备资源,实现多道程序设计
设备分配方式
独占型外围设备:一次只能由一个进程独占使用
分配方式:
- 静态分配:进程运行前申请
- 实现简单,能防止死锁,但会降低设备利用率
- 动态分配:进程随用随申请
- 提高设备利用率
设备分配数据结构:
设备类表、设备表
磁盘物理结构
存取时间 = 寻道时间 + 1/(2*磁盘旋转速度) + 传送字节数/(一个磁道字节数*磁盘旋转速度)
磁盘驱动调度
磁盘调度:
- 磁盘可能同时接收到若干I/O请求
- 随机响应I/O请求,会得到很坏的性能
- 驱动调度:OS的磁盘调度策略,即按照最佳次序执行处理访问磁盘的多个I/O请求,以减少磁盘访问的总处理时间
- 驱动调度策略包括
- 移臂调度
- 旋转调度
移臂调度
先来先服务、最短查找时间优先
单向扫描:移动臂向一个方向扫描,归途不提供服务,适用于不断有均匀分布的大量柱面请求的情形
双向扫描:移动臂每次向一个方向移动,遇到最近的I/O请求便进行处理,到达最后一个柱面后再向相反方向移动
电梯调度:双向扫描的改进,当前移动方向没有访问请求时,就改变移动方向
旋转调度
目的:使得旋转延迟的总时间最少
循环排序:
- 通过优化I/O请求排序,在最少旋转圈数内完成位于同一柱面的访问请求
- 旋转位置测定硬件和多磁头同时读写技术有利于提高旋转调度的效率
优化分布
- 通过信息在存储空间的排列方式来减少旋转延迟
- 交替排序:由于磁盘匀速运转,可能处理当前扇区数据时,下个扇区已经跳过。因此,可对扇区间隔编号,如交叉因子为n:1表示相邻编号间会间隔n-1个扇区
- 把相邻扇区集中成簇读写
- 按柱面集中存储数据(另一种集簇方式),可以减少数据读写时的移臂操作
虚拟设备
SPOOLing系统
虚拟设备技术:
- 使用一类物理设备模拟另一类物理设备的技术
- 示例:内存卡模拟磁盘、块设备模拟字符设备、输入输出重定向……
经典的SPOOLing系统:
SPOOLing (外部设备联机并行操作),即Simultaneous Peripheral Operations On-Line的缩写,它是关于慢速字符设备如何与计算机主机交换信息一种技术,通常称为“假脱机技术”。
用高速的磁盘设备来模拟慢速的字符设备,缩短进程在内存中的驻留时间
慢速输出设备先输出到(输出井)
进程运行过程中只从输入井读入数据,只向输出井输出信息,使得全部I/O都基于磁盘
加快进程周转时间,提高系统吞吐量
该SPOOLing系统的软件组成:
- 预输入程序:预先把数据从输入设备传送到磁盘输入井
- 缓输出程序:把数据从磁盘输出井传送到输出设备
- 井管理程序:控制作业进程和井之间的数据交换(事实上是I/O重定向)
打印SPOOLing系统
- 打印机守护进程和SPOOLing打印目录
- 守护进程是唯一有特权使用打印机设备的进程
- 打印文件前,用户进程先产生完整的待输出文件,并存放在打印目录下
- 打印机空闲时,启动守护进程,打印待输出文件
SPOOLing系统与作业处理:
SPOOLing作业预输入->预输入完成->作业调度->进程运行->作业调度(作业终止并撤离)->SPOOLing作业缓输出
文件管理
文件概念
文件是具有符号名的,在逻辑上具有完整意义的一组相关信息项的序列
文件命名一般包括文件名和扩展名
文件分类,用途、保护级别、信息时限、设备类型……
引入文件优点:
- 用户使用方便
- 文件安全可靠
- 文件可备份
- 文件可共享
总之,把数据组织成文件形式加以管理和控制是计算机数据管理的重大进展
文件系统
文件系统是操作系统中负责存取和管理信息的模块,它用统一的方式管理用户和系统信息的存储、检索、更新、共享和保护,并为用户提供一整套方便有效的文件使用和操作方法
文件系统中的文件:
文件这一术语不但反映了用户概念中的逻辑结构,而且和存放它的辅助存储器(也称文件存储器)的存储结构紧密相关
同一个文件必须从逻辑文件和物理文件两个侧面来观察它
文件系统作用:
文件系统面向用户的功能是:
- 文件的按名存取
- 文件的共享和保护
- 文件的操作和使用
文件存储
卷和块:
- 文件存储介质有磁带、光盘和磁盘
- 卷是存储介质的物理单位,对应于一盘磁带、一块软盘、一个光盘片、一个硬盘分区
- 块是存储介质上连续信息所组成的一个区域,也叫做物理记录
- 块在主存储器和辅助存储器进行信息交换的物理单位,每次总是交换一块或整数块信息
决定块的大小要考虑用户使用方式、数据传输效率和存储设备类型等多种因素
不同类型的存储介质,块的长短常常各不相同;对同一类型的存储介质,块的大小一般相同,但也可以不同
外围设备由于启停机械动作或识别不同块的要求,两个相邻块之间必须留有间隙,间隙是块之间不记录用户代码信息的区域
顺序存取存储设备:严格依赖信息的物理位置次序进行定位和读写,如磁带机、光盘
直接存取存储设备:存取速度高,每个物理记录有确定的位置和唯一的地址,存取任何一个物理块所需的时间几乎不依赖于此信息的位置,如磁盘
文件逻辑结构
逻辑文件:文件的逻辑结构,独立于物理环境的,用户概念中的抽象信息组织方式,用户能观察到的,并加以处理的数据集合
分类:
- 流式文件:文件内的数据不再组成记录,只是由一串依次的字节组成的信息流序列
- 记录式文件:一种有结构的文件,它是若干逻辑记录信息所组成的记录流文件
逻辑记录是文件中按信息在逻辑上的独立含义所划分的信息单位
如,每个职工的工资信息是一个逻辑记录;整个单位职工的工资信息便组成了该单位工资信息的记录式文件
记录式文件与数据库
- 数据库管理系统也支持逻辑记录
- 但数据库有别于记录式文件,数据库中的记录之间可以通过数据冗余构成某种联系
- 数据库管理系统支持基于联系的数据查询,文件系统则不行
记录成组和分解
成组与分解的提出
- 一个物理记录只存放一个逻辑记录可能造成极大的浪费
- 若干个逻辑记录合并成一组,写入一个块叫记录的成组,每块中的逻辑记录数称块因子
- 对于流式文件,一个物理记录可以存放很多个连续字节
成组与分解操作
- 系统设置独立于用户数据区的输入/输出缓冲区
- 记录的成组操作在输出缓冲区内进行,凑满一块后才将缓冲区内的信息写到存储介质上
- 当存储介质上的一个物理记录读进输入缓冲区后,把逻辑记录从块中分离出来的操作叫记录的分解操作
成组与分解的特征
- 优点:记录成组与分解不仅节省存储空间,还能减少输入输出操作次数,提高系统效率
- 记录成组与分解处理带来的新特征:
- 用户读请求,导致包含该逻辑记录的物理块读入输入缓冲区;这一操作可能读入了多个逻辑记录,这一现象称为提前读
- 用户写请求,首先是写入输出缓冲区,只有当该缓冲区中的逻辑记录满后才会引起实际输出,这一现象称为推迟写
文件物理结构
文件的物理结构和组织是指文件在物理存储空间中的存放方法和组织关系,其优劣直接影响文件系统的性能
顺序文件:逻辑上连续存放到依次紧邻的块中,读取记录速度较快,缺点要预先确定文件长度,修改、插入、增加文件记录困难
连接文件:连接结构的特点是使用连接字来表示文件中各个物理块之间的先后次序,第一块文件信息的物理地址由文件目录给出,而每一块的连接字指出了文件的下一个物理块位置;连接字内容为0时,表示文件至本块结束,输入井、输出井等,优点易于增、删、改,易于动态增加记录,不必预先确知文件长度,存储空间利用率高,缺点存放指针需要额外存储空间,仅适用于顺序存取
直接文件:散列文件,过计算记录的关键字建立与其物理存储地址之间的对应关系,想起了数据结构里面对数据进行存储的例子
索引文件:为每个文件建立了一张索引表,其中,每个表目包含一个记录的键(或逻辑记录号)及其存储地址,索引表的地址可由文件目录指出,查阅索引表先找到相应记录键(或逻辑记录号),然后获得数据存储地址。
- 索引区和数据区
- 需两步操作:第一步查找索引表,第二步获得记录物理地址
- 需要两次访问辅助存储器,若文件索引已预先调入主存储器,那么,就可减少一次内外存信息交换
- 优点:连接文件的优点,具有读写一个记录的能力,便于文件增删改
- 缺点:增加索引表空间开销和查找时间
索引表的组织:
- 一级索引
- 二级索引
- 多级索引
文件目录
文件目录是实现文件的“按名存取”的关键数据结构
文件目录需要永久保存,因此也组织成文件存放在磁盘上,称目录文件
一级目录结构——一张线性表,容易重名,不利记忆
二级目录结构——第一级为主文件目录,它用于管理所有用户文件目录,第二级为用户的文件目录,它为该用户的每个文件保存一个登记栏,其内容与一级目录的目录项相同,每一用户只允许查看自己的文件目录
- 用户文件的私有性得到保证,实现了对文件的保密和保护,由于各自有不同的用户文件目录而不会导致混乱
- 对于同一个用户而言,同样存在文件多、容易重名问题
树形目录结构——每一级目录可以登记下一级目录,也可以登记文件,从而,形成了层次文件目录结构
- 较好地反映现实世界中具有层次关系的数据集合和较确切地反映系统内部文件的组织结构
- 不同文件可以重名,只要它们不位于同一末端的子目录中
- 易于规定不同层次或子树中文件的不同存取权限,便于文件的保护、保密和共享
- 树形目录结构中的文件定位:一个文件的全名包括从根目录开始到文件为止,通路上遇到的所有子目录路径,又称为路径名
文件目录管理:
- 文件查找
- 文件查找是文件目录管理的重要工作,根据用户提供的文件路径名来搜索各级文件目录,绝对路径、相对路劲
- 目录项查找:
- 可以采用顺序查找法,依次扫᧿ 文件目录中的目录项,将目录项中的名字与欲查找的文件名相比较
- 一些优化办法加快查找目录的速度,二分查找法、杂凑法
文件目录处理:
一种有效办法是把常用和正在使用的那些文件目录复制进主存,这样,既不增加太多的主存开销,又可明显减少目录查找时间
活动文件表:
系统可以为每个用户进程建立一张活动文件表,当用户使用一个文件之前,先通过“打开”操作,把该文件有关目录信息复制到指定主存区域,有关信息填入活动文件表,以建立用户进程和该文件索引的联系
当不再使用该文件时,使用“关闭”,切断用户进程和这个文件的联系,同时,若该目录已被修改过,则应更新辅存中对应的文件目录
文件安全
-
文件共享是指不同用户共同使用某些文件
-
文件保密则是指防止文件及其内容被其他用户窃取
文件共享的并发控制、文件的保密措施(隐蔽文件目录、设置口令、使用密码)
文件保护
- 文件保护是指防止文件被破坏
常用的文件保护办法
文件副本、文件存取矩阵与文件存取表、文件属性
文件副本:
动态多副本、文件转储
文件存取控制矩阵:
- 系统为每个用户设置访问每个文件对象的存取属性
- 系统的全部用户对全部文件的存取属性就组成的一个二维矩阵,称为存取控制矩阵
- 存取控制表:由于操作系统拥有很多用户和众多文件,存取控制矩阵是一个稀疏矩阵,可以将其简化为一张存取控制表;每行包括:用户、文件、存取属性;存取控制表仅登记那些对文件拥有存取属性的部分
文件属性:
存取控制表的一种简化方法是用户分类,再针对每类用户规定文件属性
用户分类:属主、合作者、其他
文件存取方法
文件存取方法是操作系统为用户程序提供的使用文件的技术和手段
文件存取方法在某种程度上依赖于文件的物理结构
顺序存取、直接存取、索引存取
实际的系统中,大都采用多级索引,以加速记录查找过程
文件的使用
用户通过两类接口与文件系统联系:
- 第一类是与文件有关的操作命令,例如,UNIX中的cat,cd,cp,find,mv,rm,mkdir,rmdir等等
- 第二类是提供给用户程序使用的文件类系统调用,基本文件类系统调用有:建立、打开、读/写、定位、关闭、撤销
建立文件:
- 用于创建一个文件
- 所需参数:文件名、设备类(号)、文件属性及存取控制信息
撤销文件:
- 用于删除一个文件
- 所需参数:文件名和设备类(号)
打开文件:
- 用于建立起文件和用户进程之间的使用联系
- 所需参数:文件名、设备类(号)、打开方式
关闭文件:
- 用于结束一个文件的读写
- 所需参数:文件句柄
读/写文件:
- 用于读写文件
- 所需参数参数:文件句柄、用户数据区地址、读写的记录或字节个数
定位文件:
- 用于调整所打开文件的读写指针位置
- 所需参数:文件句柄,定位指针
辅存空间管理
磁盘等大容量辅存空间被OS及许多用户共享,用户进程运行期间常常要建立和删除文件,OS应能自动管理和控制辅存空间
随着用户文件不断建立和撤销,文件存储空间会出现许多‘碎片’,OS解决‘碎片’的办法是整理‘碎片’;在整理过程中,往往对文件重新组织,让其存放在连续存储区中
辅存空间的分配方式:
- 连续分配:存放在辅存空间连续存储区中
- 优点是顺序访问时速度快,管理较为简单,但为了获得足够大的连续存储区,需定时进行‘碎片’整理
- 非连续分配:动态分配给若干扇区或簇
- 优点是辅存空间管理效率高,便于文件动态增长和收缩
空闲块管理:位示图,表中每一字位对应一个物理块,字位的次序与块的相对次序一致。字位为“1”表示相应块已占用,字位为“0”状态表示该块空闲
主要优点是,可以把位示图全部或大部分保存在主存中,再配合现代计算机都具有的位操作指令,可实现高速物理块分配和去配
空闲块的管理:空闲块成组连接法
文件系统实现层次
用户接口
逻辑文件控制子系统
文件保护子系统
物理文件控制子系统
I/O控制子系统
并发控制
并发进程的分类
并发进程分类:无关的,交互的
- 无关的并发进程:一个进程的执行与其他并发进程的进展无关
- 并发进程的无关性是进程的执行与时间无关的一个充分条件,又称为Bernstein条件
- 交互的并发进程: 不满足Bernstein条件,一个进程的执行可能影响其他并发进程的结果
计算引用变量集和改变变量集是否满足Bernstein条件
与时间有关的错误:对于一组交互的并发进程,执行的相对速度无法相互控制,各种与时间有关的错误就可能出现。
与时间有关错误的表现形式:结果不唯一、永远等待
经典:机票问题、主存管理问题
进程的交互:竞争与协作
- 竞争
- 带来问题:死锁、饥饿
- 死锁解决方案:进程的互斥
- 协作
- 进程的同步,进程互斥是一种特殊的进程同步关系
临界区管理
并发进程中与共享变量有关的程序段叫“临界区”(critical section),共享变量代表的资源叫“临界资源
如果保证进程在临界区执行时,不让另一个进程进入临界区,即各进程对共享变量的访问是互斥的,就不会造成与时间有关的错误
互斥与临界区
临界区调度原则(Dijkstra, 1965):
- 一次至多一个进程能够进入临界区内执行
- 如果已有进程在临界区,其他试图进入的进程应等待
- 进入临界区内的进程应在有限时间内退出,以便让等待进程中的一个进入
Peterson算法
实现临界区管理的硬件设施
关中断:实现互斥的最简单方法
测试并建立指令
对换指令
信号量、PV操作
临界区管理的简单方法(忙式等待/反复测试)
- (1) 关中断
- (2) 测试并建立指令
- (3) 对换指令
- (4) Peterson算法
- 存在的问题
- (1)对不能进入临界区的进程,采用忙式等待测试法,浪费CPU时间
- (2)将测试能否进入临界区的责任推给各个竞争的进程会削弱系统的可靠性,加重用户编程负担
- 通用的解决方案:信号量与PV操作
设s为一个记录型数据结构,一个分量为整型量value,另一个为信号量队列queue, P和V操作原语定义:
- P(s):将信号量s减去1,若结果小于0,则调用P(s)的进程被置成等待信号量s的状态
- V(s):将信号量s加1,若结果不大于0,则释放(唤醒)一个等待信号量s的进程,使其转换为就绪态
- 原语:CPU处于内核态,在关中断环境下执行的一段指令序列
强调:对于信号量,只允许使用P和V原语操作访问信号量,不能直接对信号量的整型值做读写操作,也不能直接对信号量的队列做任何其他操作
管程
为什么要引入管程?
- 把分散在各进程中的临界区集中起来进行管理
- 防止进程有意或无意的违法同步操作
- 便于用高级语言来书写程序
管程的定义
-
管程是由局部于自己的若干公共变量及其说明和所有访问这些公共变量的过程所组成的软件模块
-
管程的属性
- 共享性
- 安全性
- 互斥性
-
条件变量-是出现在管程内的一种数据结构,且只有在管程中才能被访问,它对管程内的所有过程是全局的,只能通过两个原语操作来控制它
-
wait( )-阻塞调用进程并释放管程,直到另一个进程在该条件变量上执行signal( )
-
signal( )-如果存在其他进程由于对条件变量执行wait( )而被阻塞,便释放之;如果没有进程在等待,那么,信号不被保存
-
使用signal释放等待进程时,可能出现两个进程同时停留在管程内。解决方法:
- 执行signal的进程等待,直到被释放进程退出管程或等待另一个条件变量
- 被释放进程等待,直到执行signal的进程退出管程或等待另一个条件
-
霍尔(Hoare, 1974)采用第一种办法
-
汉森(Hansen)选择两者的折衷,规定管程中的过
程所执行的signal操作是过程体的最后一个操作
管程的实现 (Hoare方法)
- 霍尔方法使用P和V操作原语来实现对管程中过程的互斥调用,及实现对共享资源互斥使用的管理
- 不要求signal操作是过程体的最后一个操作,且wait和signal操作可被设计成可以中断的过程
mutex
- 对每个管程,使用用于管程中过程互斥调用的信号量mutex (初值为1)
- 进程调用管程中的任何过程时,应执行P(mutex);进程退出管程时,需要判断是否有进程在next信号量等待,如果有(即next_count>0),则通过V(next)唤醒一个发出signal的进程,否则应执行V(mutex)开放管程,以便让其他调用者进入
- 为了使进程在等待资源期间,其他进程能进入管程,故在wait操作中也必须执行V(mutex),否则会妨碍其他进程进入管程,导致无法释放资源
next和next-count
- 对每个管程,引入信号量next(初值为0),凡发出signal操作的进程应该用P(next)阻塞自己,直到被释放进程退出管程或产生其他等待条件
- 进程在退出管程的过程前,须检查是否有别的进程在信号量next上等待,若有,则用V(next)唤醒它。next-count(初值为0),用来记录在next上等待的进程个数
x-sem和 x-count
- 引入信号量x-sem(初值为0),申请资源得不到满足时,执行P(x-sem)阻塞。由于释放资源时,需要知道是否有别的进程在等待资源,用计数器x-count(初值为0)记录等待资源的进程数
- 执行signal操作时,应让等待资源的诸进程中的某个进程立即恢复运行,而不让其他进程抢先进入管程,这可以用V(x-sem)来实现
每个管程定义如下数据结构 :
typedef struct InterfaceModule { //InterfaceModule是结构体名字
semaphore mutex; //进程调用管程过程前使用的互斥信号量
semaphore next; //发出signal的进程阻塞自己的信号量
int next_count; //在next上等待的进程数
};
mutex=1; next=0; next_count=0; //初始化语句
Hoare管程的enter( )和leave( )操作:
void enter(InterfaceModule &IM) {
P(IM.mutex); //判断有否发出过signal的进程?
}
void leave(InterfaceModule &IM) {
if (IM.next_count>0)
V(IM.next); //有就释放一个发出过signal的进程
else
V(IM.mutex); //否则开放管程
}
Hoare管程的wait( )操作:
void wait(semaphore &x_sem,int &x_count,InterfaceModule &IM) {
x_count++; //等资源进程个数加1,x_count初始化为0
if (IM.next_count>0) //判断是否有发出过signal的进程
V(IM.next); //有就释放一个
else
V(IM.mutex); //否则开放管程
P(x_sem); //等资源进程阻塞自己,x_sem初始化为0
x_count–; //等资源进程个数减1
}
Hoare管程的signal( )操作:
void signal(semaphore &x_sem,int &x_count,InterfaceModule &IM) {
if(x_count>0) { //判断是否有等待资源的进程
IM.next_count++; //发出signal进程个数加1
V(x_sem); //释放一个等资源的进程
P(IM.next); //发出signal进程阻塞自己
IM.next_count–; //发出signal进程个数减1
}
有(即next_count>0),则通过V(next)唤醒一个发出signal的进程,否则应执行V(mutex)开放管程,以便让其他调用者进入
- 为了使进程在等待资源期间,其他进程能进入管程,故在wait操作中也必须执行V(mutex),否则会妨碍其他进程进入管程,导致无法释放资源
next和next-count
- 对每个管程,引入信号量next(初值为0),凡发出signal操作的进程应该用P(next)阻塞自己,直到被释放进程退出管程或产生其他等待条件
- 进程在退出管程的过程前,须检查是否有别的进程在信号量next上等待,若有,则用V(next)唤醒它。next-count(初值为0),用来记录在next上等待的进程个数
x-sem和 x-count
- 引入信号量x-sem(初值为0),申请资源得不到满足时,执行P(x-sem)阻塞。由于释放资源时,需要知道是否有别的进程在等待资源,用计数器x-count(初值为0)记录等待资源的进程数
- 执行signal操作时,应让等待资源的诸进程中的某个进程立即恢复运行,而不让其他进程抢先进入管程,这可以用V(x-sem)来实现
每个管程定义如下数据结构 :
typedef struct InterfaceModule { //InterfaceModule是结构体名字
semaphore mutex; //进程调用管程过程前使用的互斥信号量
semaphore next; //发出signal的进程阻塞自己的信号量
int next_count; //在next上等待的进程数
};
mutex=1; next=0; next_count=0; //初始化语句
Hoare管程的enter( )和leave( )操作:
void enter(InterfaceModule &IM) {
P(IM.mutex); //判断有否发出过signal的进程?
}
void leave(InterfaceModule &IM) {
if (IM.next_count>0)
V(IM.next); //有就释放一个发出过signal的进程
else
V(IM.mutex); //否则开放管程
}
Hoare管程的wait( )操作:
void wait(semaphore &x_sem,int &x_count,InterfaceModule &IM) {
x_count++; //等资源进程个数加1,x_count初始化为0
if (IM.next_count>0) //判断是否有发出过signal的进程
V(IM.next); //有就释放一个
else
V(IM.mutex); //否则开放管程
P(x_sem); //等资源进程阻塞自己,x_sem初始化为0
x_count–; //等资源进程个数减1
}
Hoare管程的signal( )操作:
void signal(semaphore &x_sem,int &x_count,InterfaceModule &IM) {
if(x_count>0) { //判断是否有等待资源的进程
IM.next_count++; //发出signal进程个数加1
V(x_sem); //释放一个等资源的进程
P(IM.next); //发出signal进程阻塞自己
IM.next_count–; //发出signal进程个数减1
}
}