操作系统
约 7236 字大约 24 分钟
2025-04-08
一、操作系统概念
1.1 操作系统的大体概念
操作系统(os)是指控制盒管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;他是计算机系统中最基本的系统软件。
作为系统资源的管理者
提供的功能
- 处理器管理
- 存储器管理
- 文件管理
- 设备管理
目标
- 安全、高效
ps: 执行一个程序前需要将该程序放到内存中,才能被 cpu 处理
操作系统的功能和目标——向上层提供方便易用的服务
用户 应用程序 操作系统 裸机(纯硬件) 向上层提供方便易用的服务
- 直接给用户使用的
- GUI(图形用户界面)
- 命令接口
- 联机命令接口
- 脱机命令接口
- 给软件给程序员使用的
- 程序接口
- 直接给用户使用的
1.2 操作系统的四个特征
操作系统的特征
并发
宏观上是同时发生,微观上是交替发生的
共享
互斥共享方式
一个时间段内只允许一个进程访问该资源
同时共享方式
允许一个时间段内有多个进程“同时”对他们进行访问
虚拟
是指吧一个物理上的实体变为若干个逻辑上的对应物。物理实体(前者)是实际存在的,而逻辑上对应物(后者)是用户感受到的。
- 空分复用技术(例如虚拟存储器技术)
- 时分复用技术(例如虚拟处理器)
异步
是指在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。
1.3 操作系统的发展与分类
手工操作阶段
主要缺点:用户独占全机、人机速度矛盾导致资源利用率极低
批处理阶段
单道批处理系统
引入脱机输入/输出技术(用外围机+磁带来完成),并由监督程序负责作业的输入、输出
主要优点:缓解了一定程度的人机速度矛盾,资源利用率有所提升。
主要缺点:内存中技能有一道程序运行,只有该程序运行结束之后才能调入下一道程序。cpu 有大量的时间在等待 I/O 完成。资源利用率依然很低。
多到批处理系统(操作系统开始出现)
主要优点:多道程序并发执行,共享计算机资源。资源利用率大幅度提升,cpu 和其他资源更能保持“忙碌‘’状态,系统吞吐量增大。
主要缺点:用户响应时间长,没有人机交互功能(用户提交自己的作业之后就只能等待计算机处理完成,中间不能控制自己的作业执行。eg:无法调试程序/无法在程序运行过程中输入一些参数)
分时操作系统
计算机以时间片为单位轮流为各个用户/作业服务,各个用户可通过终端与计算机进行交互
主要优点:用户请求可以被及时响应,解决了人机交互问题。允许多个用户同时使用一台计算机,并且用户对计算机的操作相互独立,感受不到别人的存在。
主要缺点:不能优先处理一些紧急任务。操作系统对各个用户/作业都是完全公平的,循环地为每个用户/作业服务一个时间片,不区分任务的紧急性。
实时操作系统
主要优点:能够优先响应一些紧急任务,某些紧急任务不需时间片排队
在实时操作系统的控制下,计算机系统接收到外部信号后及时进行处理,并且要在严格的时限内处理完事件。实时操作系统的主要特点是及时性和可靠性
硬实时系统(例如导弹控制系统、自动驾驶系统)
必须在绝对严格的规定时间内完成处理
软实时系统(例如 12306)
能接受偶尔违反时间规定
网络操作系统
能伴随着计算机网络的发展而诞生的,能把网络中各个计算机有机的结合起来,实现数据传送等功能,实现网络中各种资源的共享(如文件共享)和各台计算机之间的通信(例如 windows nt)
分布式操作系统
主要特点是分布性和并行性。系统中的各台计算机地位相同,任何工作都可以分布在这些计算机上,由它们并行、协同完成这个任务
个人计算机操作系统(windows xp、mac os)
1.4 操作系统的运行机制
预备知识:程序是如何运行的?
c 语言代码-> 机器指令(中间的过程编译汇编链接装载)
程序的运行过程其实就是 cpu 执行一条条的机器指令的过程
“指令”就是指处理器能识别、执行的最基本命令
要注意区分交互式命令接口与指令
内核(kernel)程序 vs 应用程序
- 普通程序员写的程序就是“应用程序”
- 开发操作系统的就是写的“内核程序”
两种指令
cpu 在设计支出划分了特权指令和非特权指令,执行一条指令前就能判断出其类型
- 特权指令
- 非特权指令
两种处理器状态
cpu 中有一个寄存器叫程序状态字寄存器(PSW),其中有个二进制位,1 表示“内核态”,0 表示“用户态”
别名:内核态 = 核心态 = 管态;用户态 = 目态
- 核心态
- 用户态
两种程序
- 内核程序
- 应用程序
内核
- 内核是操作系统中最重要最核心的部分
- 有很多内核程序组成操作系统内核
如何变态?
- 内核态-> 用户态——一条修改 PSW 的特权指令
- 用户态-> 内核态——由中断引起,硬件自动完成
1.5 中断和异常
中断的作用
cpu 上会运行两种程序,一种是操作系统内核程序,一种是应用程序
在合适的情况下,操作系统内核会把 cpu 的使用权主动让给应用程序
“中断”是让操作系统内核夺回 cpu 使用权的唯一途径
关联并发
中断的类型
大多数的教材中。“中断”特指狭义的中断,即外中断。而内中断一般称为“异常”
内中断(也称“异常”、“例外”)
- 终止——试图在用户态下执行特权指令
- 故障——执行除法指令时发现除数为 0
- 陷阱、陷入(trap)——有时候应用程序想请求操作系统内核的服务,此时会执行一条特殊的指令——陷入指令,该指令会引发一个内部中断信号
与当前执行的指令有关,中断信号来源于 cpu 内部
外中断(也称“中断”)
- 时钟中断——由时钟部件发来的中断信号
- I/O 中断请求——由输入/输出设备发来的中断信号
与当前执行的指令无关,中断信号来源于 cpu 外部
中断机制的基本原理
不同的中断信号,需要用不同的中断处理程序来处理。当 cpu 检测到中断信号后,会根据中断信号的类型去查询“中断向量表”,以此来找到相应的中断处理程序在内存中的存放位置
1.6 系统调用
什么是系统调用
“系统调用”是操作系统提供给应用程序(程序员/编程人员)使用的接口,可以理解为一种可供应用程序调用的特殊函数,应用程序可以通过系统调用来请求获得操作系统内核的服务
系统调用与库函数的区别
普通应用程序 可直接进行系统调用,也可使用库函数。有的库函数涉及系统调用,有的不涉及 编程语言 向上提供库函数。有时会将系统调用封装成库函数,以隐藏系统调用的一些细节,使程序员编程更加方便 操作系统 向上提供系统调用,使得上层程序能请求内核的服务 裸机 不涉及系统调用的库函数:如:“取绝对值”的函数
涉及系统调用的库函数:如:“创建一个新文件”的函数
小例子:为什么调用是必须的?
word 和 wps 打印文档,如果并发进行就混杂了
解决方法:由操作系统内核对共享资源进行统一的管理,并向上提供“系统调用”,用户进程想要使用打印机这种共享资源,只能通过系统调用向操作系统内核发出请求。内核会对各个请求进行协调处理
什么功能要用系统调用实现?
应用程序通过系统调用请求操作系统的服务。而系统中的各种共享资源都由操作系统内核统一掌管,因此凡是与共享资源有关的操作(如存储分配、I/O 操作、文件管理等),都必须通过系统调用的方式向操作系统内核提出服务请求,由操作系统内核代为完成。这样可以保证系统的稳定性和安全性,防止用户进行非法操作
- 按功能分类
- 设备管理——完成设备的 请求/释放/启动 等功能
- 文件管理——完成文件的 读/写/创建/删除 等功能
- 进程控制——完成进程的 创建/撤销/阻塞/唤醒 等功能
- 进程通信——完成进程之间的 消息传递/信号传递 等功能
- 内存管理——完成内存的 分配/回收 等功能
- 按功能分类
系统调用的过程
- 传参
- 陷入指令/trap/访管
- 由操作系统内核程序处理系统调用请求
- 返回应用程序
陷入指令是在用户态执行的,执行陷入指令之后立即引发一个内中断,使 cpu 进入核心态
发出系统调用请求是在用户态,而对系统调用的相应处理在核心态下进行
1.7 操作系统的体系结构
用户 |
---|
应用程序 |
非内核功能(如 GUI) |
进程管理、存储器管理、设备管理等功能 |
时钟管理 中断处理 原语(设备驱动、cpu 切换等) |
裸机 |
利用时钟中断实现计时功能
原语是一种特殊的程序,具有原子性,也就是说,这段程序的运行必须一气呵成,不可被“中断”
ubuntu、centos 的开发团队,其主要工作室实现非内核功能,而内核都是用了 linux 内核
典型的内核操作系统
- 大内核:Linux、UNIX
- 微内核:Window NT
变态的过程是有成本的,频繁的变态会降低系统性能
大内核(又名:宏内核/单内核)两次变态
- 内核态
- 进程管理
- 存储管理
- 时钟管理、中断管理、原语
- 优点:高性能
- 缺点:内核代码庞大,结构混乱,难以维护
- 内核态
微内核 六次变态
用户态
- 进程管理
- 存储管理
- 设备管理
内核态
- 时钟管理、中断管理、原语
优点:内核功能少,结构清晰,方便维护
缺点:需要频繁地在核心态和用户态之间切换,性能低
分层结构
- 最底层是硬件,最高层是用户接口,每层可调用更低一层
- 优点
- 便于调试和验证,自底向上逐层调试验证
- 易扩充和易维护,各层之间调用接口清晰固定
- 缺点
- 仅可调用相邻低层,难以合理定义各层的边界
- 效率低,不可跨层调用,系统调用执行时间长
模块化
将内核划分为多个模块,各模块之间相互协作
内核 = 主模块+可加载内核模块
主模块只负责核心功能,如进程调度、内存管理
可加载内核模块:可以动态加载新模块到内核,而无需重新编译整个内核
优点
- 模块间逻辑清晰易于维护,确定模块间接口后即可多模块同时开发
- 支持动态加载新的内核模块(如:安装设备驱动程序、安装新的文件系统模块到内核),增强 OS 适应性
- 任何模块都可以直接调用其他模块,无需采用消息传递进行通信,效率高
缺点
- 模块间的接口定义未必合理、实用
- 模块间相互依赖、更难调试和验证
外核
- 内核负责进程调度、进程通信等功能,外核负责为用户进程分配未经抽象的硬件资源,且由外核负责保证资源使用安全
- 优点
- 外核可直接给用户进程分配“不虚拟、不抽象”的硬件资源,使用户进程可以更灵活的使用硬件资源
- 减少了虚拟硬件资源的“映射层”,提升效率
- 缺点
- 降低了系统的一致性
- 使系统变得更复杂
1.8 操作系统引导
- cpu 从一个特定的主存地址开始,取指令,执行 ROM 中的引导程序(先进行硬件自检,再开机)
- 将磁盘的第一块——主引导记录 读入内存,执行磁盘引导程序,扫描分区表
- 从活动分区(又称主分区,即安装了操作系统的分区)读入分区引导记录,执行其中的程序
- 从根目录下找到完整的操作系统初始化程序(即 启动器管理器)并执行,完成“开机”的一系列动作
1.9 虚拟机
使用虚拟化技术,将一台物理机器虚拟化为多台虚拟机器(Virtual Machine, VM),每个虚拟机器都可以独立运行一个操作系统
虚拟机管理程序/虚拟机监控程序/Virtual Machine Monitor/Hypervisor
- 第一类:直接运行在硬件上
- 第二类:运行在宿主操作系统上(vmware)
两类的对比
第一类 VMM 第二类 VMM 对物理资源的控制权 直接运行在硬件之上,能直接控制和分配物理资源 运行在 host os 之上,依赖于 host os 为其分配物理资源 资源分配方式 在安装 guest os 时,VMM 要在原本的硬盘上自行分配存储空间,类似于“外核”的分配方式,分配未经抽象的物理硬件 guest os 拥有自己的虚拟磁盘,改判实际上是 host os 文件系统中的一个大文件。guest os 分配到的内存是虚拟内存 性能 性能更好 性能更差,需要 host os 作为“中介” 可支持的虚拟机数量 更多,不需要和 host os 竞争资源,相同的硬件资源可以支持更多的虚拟机 更少,host os 本身需要使用物理资源,host os 上运行其他进程也需要物理资源 虚拟机的可迁移性 更差 更好,只需导出虚拟机镜像文件即可迁移到另一台 host os 上,商业化应用更广泛 运行模式 第一类 VMM 运行在最高特权级(Ring 0),可以执行最高特权的指令 第二类 VMM 部分运行在用户态、部分运行在内核态。guest os 发出的系统调用会被 VMM 截获,并转化为 VMM 对 host os 的系统调用
二、进程管理
2.1 进程的概念、组成、特征
概念——理解“进程”和“程序”的区别
- 程序:是静态的,就是个存放在磁盘里的可执行文件,就是一系列的指令集合
- 进程:是动态的,是程序的一次执行过程
组成——一个进程由哪些部分组成
PCB
以下信息都被保存在一个数据结构 PCB 中,即进程控制块
操作系统要记录 PID、进程用户所属用户 ID(UID)
还要记录给进程分配了哪些资源(如:分配了多少内存、正在使用哪些 I/O 设备、正在使用哪些文件)
还要记录进程的运行情况(如:cpu 使用时间、磁盘使用情况、网络流量使用情况等)
- 进程描述信息
- 进程标识符 PID
- 用户标识符 UID
- 进程控制和管理信息
- cpu、磁盘、网络流量使用情况统计···
- 进程当前状态:就绪态/阻塞态/运行态···
- 资源分配清单
- 正在使用哪些文件
- 正在使用哪些哪些内存区域
- 正在使用哪些 I/O 设备
- 处理器相关信息
- 如 PSW、PC 等等各种寄存器的值(用于实现进程切换)
- 进程描述信息
程序段——程序的代码(指令序列)
数据段——运行过程中产生的各种数据(如:程序中定义的变量)
特征——进程有哪些重要的特征
2.2 进程的状态与转换
状态
运行状态——占有 CPU 并在 CPU 上运行
当 cpu 空闲时,操作系统就会选择一个就绪进程,让它上处理机运行
如果一个进程此时在 cpu 上运行,那么这个进程处于“运行态”
就绪状态——已经具备运行条件,但由于没有空闲 CPU,而暂时不能运行
- 当进程创建完成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲 cpu,就暂时不能运行
阻塞状态——因等待某一事件而暂时不能运行
在进程运行的过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。
在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下 cpu,并让他进入“阻塞态”
当 cpu 空闲时间,又会选择另一个“就绪态” 进程上 cpu 运行
创建状态——进程正在被创建,操作系统为进程分配资源、初始化 PCB
- 进程正在被创建时,他的状态是“创建态”,在这个阶段操作系统会为进程分配资源、初始化 PCB
终止状态——进程正在从系统中撤销,操作系统会回收进程所拥有的资源、撤销 PCB
- 一个进程可以执行 exit 系统调用,请求操作系统终止改进成该进程。此时该进程会进入“终止态”,操作系统会让该进程下 cpu,并回收内存空间等资源,最后还要回收该进程的 PCB
状态间的转换
创建态-> 就绪态
系统完成创建进程的一系列工作
就绪态-> 运行态
进程被调度
运行态-> 就绪态
时间片到,或处理机被抢占
运行态-> 阻塞态
进程用“系统调用”的方式申请某种系统资源,或者请求等待某个事件的发生
阻塞态-> 就绪态
申请的资源被分配,或等待的事件发生
运行态-> 终止态
进程运行结束,或运行过程中遇到不可修复的错误
进程的组织方式(各个进程 PCB 的组织方式)
- 链接方式
- 执行指针
- 就绪队列指针
- 阻塞队列指针
- 索引方式
- 执行指针
- 就绪表指针
- 阻塞表指针
- 链接方式
2.3 进程控制
基本概念
什么是进程控制:
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。
简化理解:反正进程就是要实现进程状态转换
如何实现进程控制:用"原语实现"
- 原语是一种特殊的程序,他的执行具有原子性。也就是说,这段程序的的运行必须一气呵成,不可中断
- 可以用"关中断指令"和"开中断指令"这两个特权指令实现原子性
- CPU执行力关中断指令后,就不再理性检查中断信号,知道之星开中断指令之后才会恢复检查。这样,关中断、开中断之间的这些指令序列就是不可被中断的,这就实现了"原子性"。
进程控制相关的术语
- 进程的创建
- 创建原语
- 申请空白PCB
- 为新进程分配所需资源
- 初始化PCB
- 将PCB插入就绪队列
- 引起进程创建的事件
- 用户登录:分时系统中,用户登录成功,系统会为其建立一个新的进程
- 作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
- 提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求
- 应用请求:由用户进程主动请求创建一个子进程
- 创建原语
- 进程的终止
- 撤销原语
- 从PCB集合中找到终止进程的PCB
- 若进程正在运行,立即剥夺CPU,将CPU分配给其他进程
- 终止其所有子进程
- 将该进程拥有的所有资源归还给父进程或操作系统
- 删除PCB
- 引起进程终止的事件
- 正常结束
- 异常结束
- 外界干预
- 撤销原语
- 进程的阻塞
- 阻塞原语
- 找到要阻塞的进程对应的PCB
- 保护进程运行现场,将PCB状态信息设置为"阻塞态",暂时停止进程运行
- 将PCB插入相应事件的等待队列
- 引起进程阻塞的事件
- 需要等待系统分配某种资源
- 需要等待相互合作的其他进程完成工作
- 阻塞原语
- 进程的唤醒
- 唤醒原语
- 在事件等待队列中找到PCB
- 将PCB从等待队列移除,设置进程为就绪态
- 将PCB插入就绪队列,等待被调度
- 引起进程唤醒的事件:等待的事件发生
- 唤醒原语
- 进程的切换
- 切换原语
- 将 存入PCB
- PCB移入相应队列
- 选择另一个进程执行,并更新其PCB
- 根据PCB恢复新进程所需的运行环境
- 引起进程切换的事件
- 当前进程时间片到
- 有更高优先级的进程到达
- 当前进程主动阻塞
- 当前进程终止
- 切换原语
- 进程的创建
2.4 进程通信(IPC)
进程间通信是指两个进程之间产生数据交互
共享存储
通过"增加页表项、段表项"即可将同一片共享内存区映射到各个进程的地址空间中
为避免出错,各个进程对共享空间的访问应该是互斥的
各个进程可使用操作系统内核提供的同步互斥工具(如P\V操作)
- 基于数据结构的共享:比如共享空间里只能存放一个长度为10的数组。这种共享方式速度慢、限制多,是一种低级通信方式
- 基于存储区的共享:操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式
消息传递
进程间的数据交换以格式化的消息为单位。进程通过操作系统提供的"发送消息、接受消息"两个原语进行数据交换
消息头 消息头包括:发送进程ID、接受进程ID、消息长度等格式化的信息 消息体 具体的进程要传递的数据 - 直接通信方式:消息发送进程要指明接收进程的ID
- 间接通信方式:通过"信箱"间接的通信。因此又称"信箱通信方式"
管道
通信
- "管道"是一个特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区。循环队列
- 管道只能采用半双工通信,某一时间段内只能实现单向的传输。如果要实现双向同时通信,则需要设置两个管道
- 个进程要互斥地访问管道(由操作系统实现)
- 当管道写满时,写进程将阻塞,直到读进程将管道中的数据取走,即刻唤醒写进程
- 当管道读空时,杜进程将阻塞,直到写进程往管道中写入数据,即可唤醒读过程
- 管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:
- 一个管道允许多个写进程,一个读过程
- 允许有多个写进程,多个读进程,单系统会让各个读进程轮流从管道中读数据
2.5 线程概念多线程模型
什么是线程,为什么要引入线程?
传统的进程是程序执行流的最小单位。
有的进程可能需要"同时"做很多事,而传统的进程只能串行地执行一系列程序。为此,引入了"线程",来增加并发度。
引入线程机制后,有什么变化?
资源分配、调度
传统进程机制中,进程是资源分配、调度的基本单位
引入线程后,进程是资源分配的基本单位,线程是调度的基本单位。
并发性
- 传统进程机制中,只能进程间并发
- 引入线程后,各线程间也能并发,提升了并发度
系统开销
- 传统的进程间并发,需要切换进程的运行环境,系统开销很大
- 线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小
- 引入线程后,并发所带来的系统开销减小
线程有哪些重要的属性
- 线程是处理机调度的单位
- 多CPU计算机中,各个线程可占用不同的CPU
- 每个线程都有一个线程ID、线程控制块
- 线程也有就绪、阻塞、运行三种基本状态
- 线程几乎不拥有系统资源
- 同一进程的不同线程间共享进程的资源
- 由于共享内存地址空间,同一进程的中的线程间通信甚至无需系统干预
- 同一进程中的线程切换,不会引起进程切换
- 不同进程中的线程切换,会引起进程切换
- 切换同进程内的线程,系统开销很小
- 切换进程,系统开销较大
线程的实现方式
- 用户级线程
- 内核极线程
多线程模型
- 多对一模型
- 一对一模型
- 多对多模型
2.6 线程的实现方式和多线程模型
- 线程的实现方式
- 用户级线程:从用户视角能看到的线程,由线程库实现
- 内核级线程:由操作系统视角看到的线程,由操作系统实现(内核级线程才是处理剂分配的单位)
- 组合方式:上述两种方式的结合
- 多线程模型
- 一对一模型
- 一个用户级线程映射到一个内核级线程
- 优:各个线程可分配到多喝处理器并行执行,并发度高
- 缺:线程管理都需要操作系统支持,开销大
- 多对一模型
- 多个用户级线程映射到一个内核级线程
- 优:线程管理开销小效率高
- 缺:一个线程阻塞会导致整个进程都被阻塞(并发度低)
- 多对多模型
- n个用户级映射到m个内核级线程
- 集二者之所长
- 一对一模型