[操作系统]操作系统原理V02:从硬件抽象、进程、内存、存储到安全与虚拟化的系统性技术指南
操作系统原理
从硬件抽象、进程、内存、存储到安全与虚拟化的系统性技术指南

图:操作系统抽象层次
本文为教学和工程参考资料。示意图中的数值为概念性示例,不代表特定内核或硬件的基准测试结果。
1. 操作系统的作用
操作系统是运行在硬件之上的特权软件层,它把处理器、内存、存储和设备等资源转换为可控制、可组合的抽象。它提供进程而不是裸指令流,提供虚拟地址空间而不是物理地址,提供文件而不是设备扇区,并通过套接字隐藏网络控制器的具体操作。这些抽象降低了应用开发难度,同时为保护、计费、调度和策略执行提供了统一位置。
操作系统既是资源管理器,也是扩展机器。作为资源管理器,它决定谁可以使用CPU、内存、存储和设备、使用多长时间以及采用什么策略;作为扩展机器,它把不规则的硬件细节隐藏在稳定接口之后。抽象并不意味着硬件差异消失:局部性、负载特征和硬件拓扑仍然影响性能,因此优秀系统会暴露经过选择的控制点,而不是假设所有硬件都完全相同。
|
领域 |
核心职责 |
典型机制 |
设计权衡 |
|
进程管理 |
创建、调度、同步并终止执行上下文 |
PCB、队列、上下文切换、IPC |
吞吐量与时延 |
|
内存管理 |
分配、保护并虚拟化地址空间 |
分页、分段、TLB、回收 |
隔离性与开销 |
|
文件与存储 |
提供持久、有名且可共享的数据 |
VFS、inode、日志、缓存 |
一致性与性能 |
|
I/O管理 |
协调设备和异步事件 |
驱动、中断、DMA、缓冲 |
通用性与设备效率 |
|
保护机制 |
控制资源访问并执行安全策略 |
模式、能力、ACL、沙箱 |
安全与易用性 |
表1:操作系统的主要职责及其核心设计权衡。
- 机制回答“如何实现”,策略回答“选择什么”。
- 系统调用是从非特权执行环境受控进入内核代码的边界。
- 隔离只有在接口同时支持组合、观察和调试时才真正有价值。
- 正确性不仅包括安全性,还包括活性、公平性、可恢复性和可预测的故障行为。
1.1 内核组织方式
宏内核把许多服务放在同一个特权地址空间中,通信开销较低,但一个服务中的缺陷可能影响整个内核。微内核尽量缩小特权核心,把驱动和服务移到用户空间,从而改善故障隔离,但会增加消息传递和系统集成复杂度。混合内核结合了两种思想。比较架构时,关键不在于简单地说内核“大”或“小”,而在于分析其故障模型、性能边界和维护边界。
2. 进程、线程与并发
进程是一个隔离的执行环境,包含地址空间、资源句柄和一个或多个线程。线程是其中可以被调度的指令执行流。把资源容器和执行流分离,可以让多个活动共享代码和数据,同时保留进程级保护;代价是共享内存带来协调责任:每个共享不变量都需要同步方案,而每种同步方案又可能引入等待和顺序约束。

图2:典型进程状态及其转换。
|
状态 |
含义 |
进入条件 |
退出条件 |
|
新建 |
进程正在创建 |
程序被接纳 |
PCB初始化完成 |
|
就绪 |
可以运行但等待CPU |
可运行且驻留内存 |
调度器选中 |
|
运行 |
指令正在CPU上执行 |
调度或恢复 |
抢占、阻塞或退出 |
|
阻塞 |
等待I/O或事件 |
同步等待 |
事件完成 |
|
终止 |
执行已经结束 |
正常退出或致命错误 |
回收资源 |
表2:简化的进程状态模型。
上下文切换需要保存足够的体系结构状态,以便挂起一个线程并恢复另一个线程。它可能涉及寄存器、地址空间元数据、调度统计以及缓存和地址转换的影响。可见的切换时间只是成本的一部分:新调度线程通常还会经历缓存缺失和TLB缺失。因此,高性能系统会在允许的情况下使用局部性感知调度、CPU亲和性和批处理。
2.1 同步与死锁
互斥锁用于互斥访问,信号量表示计数资源,条件变量允许线程等待某个谓词可能成立,读写锁区分读者和写者。这些原语不会自动保证程序正确。可靠设计需要记录所有权、锁顺序、中断行为以及每把锁保护的不变量。死锁可以用Coffman四个条件分析:互斥、占有且等待、不可剥夺和循环等待。破坏其中任意一个条件,就可以避免该类死锁。
- 优先使用少量且所有权明确的锁,避免形成没有文档的锁图。
- 临界区应尽量短,但不能在不变量恢复前释放锁。
- 如果无限等待不可接受,应设计超时、取消和看门狗机制。
- 需要测量竞争和尾延迟;平均锁耗时可能掩盖严重排队。
3. CPU调度与资源分配
调度器从可运行线程中选择下一个获得处理器时间的线程。调度需要在吞吐量、响应时间、公平性、能耗、截止期和迁移成本之间权衡。不存在适合所有负载的单一策略:交互任务重视快速响应,批处理任务重视连续执行和缓存局部性,实时任务则需要可调度性论证,而不仅是较低的平均延迟。

图3:调度策略权衡示意;评分为概念性示例,不代表基准测试。
|
策略 |
选择规则 |
适用场景 |
常见缺点 |
|
FCFS |
先到先服务 |
简单批处理 |
护航效应 |
|
时间片轮转 |
按时间片循环服务 |
交互式公平调度 |
时间片需要调优 |
|
优先级 |
优先选择有效优先级最高的任务 |
紧急或实时任务 |
没有老化机制时可能饥饿 |
|
多级反馈队列 |
根据行为动态移动任务 |
混合交互与计算负载 |
策略行为复杂 |
|
最早截止期优先 |
优先处理截止期最近任务 |
动态实时任务 |
过载时需要额外管理 |
表3:代表性的CPU调度策略。
抢占使用定时器或其他事件,从运行中的任务重新取得控制权。优先级反转是指高优先级任务等待低优先级任务持有的锁,而中优先级任务持续运行。优先级继承会临时提高锁持有者的有效优先级;优先级上限则根据任务可能获取的资源制定协议。这说明调度和同步不能完全分开设计。
3.1 多处理器与加速器
在多核系统中,调度器必须考虑共享缓存、NUMA内存、中断分布和温度限制。工作窃取可以让空闲工作线程从其他队列取得任务,但可能破坏局部性。CPU亲和性可以减少迁移,对延迟敏感服务很重要。GPU及其他加速器增加了另一个调度域,需要协调命令队列、数据传输和内核启动开销。
- 先定义服务目标,再选择调度器:吞吐量、P99延迟、错过截止期的比例或能耗。
- 把准入控制与派发分开;不可能的负载无法靠调度消除过载。
- 细粒度任务需要把测量开销纳入设计。
4. 内存管理与虚拟化
虚拟内存为每个进程提供受保护的地址空间,并允许操作系统灵活安排物理内存中的数据。分页把地址分成虚拟页号和页内偏移,页表把虚拟页号转换为物理页框。TLB缓存近期转换结果。TLB缺失时,硬件或软件需要遍历页表;发生缺页时,操作系统还要检查访问权限、分配页框、从存储取回数据,或终止非法进程。

图4:虚拟页到物理页框的概念映射。
|
技术 |
核心思想 |
优势 |
代价或风险 |
|
分页 |
固定大小的虚拟页映射到物理页框 |
分配和隔离相对简单 |
页表开销与TLB缺失 |
|
请求分页 |
仅在访问时加载页面 |
降低初始内存占用 |
缺页可能带来较大延迟 |
|
写时复制 |
写入前共享页面,写入时再复制 |
进程创建速度快 |
写缺页与资源记账复杂 |
|
内存映射文件 |
将文件区域映射到地址空间 |
便于共享和随机访问 |
一致性与淘汰策略复杂 |
|
NUMA放置 |
让数据靠近执行CPU |
适合多路系统扩展 |
放置和迁移管理复杂 |
表4:内存管理技术及其工程权衡。
内存管理不只是分配。内核还要跟踪所有权、权限、共享关系和回收过程。页面置换策略尝试淘汰近期不太可能使用的页面;近似LRU会利用硬件访问位和脏位,工作集思想则描述进程当前活跃的局部性。过度分页会形成颠簸,使机器花费更多时间搬运页面,而不是执行有用计算。
4.1 容器与虚拟机
虚拟机模拟或虚拟化完整硬件平台,使客户操作系统与宿主机保持较强边界。容器通常共享宿主机内核,通过命名空间、资源限制、进程隔离和文件系统视图实现隔离。硬件辅助虚拟化可以降低特权切换成本,但仍需考虑设备访问、侧信道、资源争用和生命周期管理。
- 对地址空间映射和设备能力使用最小权限。
- 在容器或租户维度跟踪内存压力,不要只看全局剩余内存。
- 在压力环境下测试fork、快照、迁移和回收路径,因为最难的情况通常不在稳态。
5. 文件系统、存储与I/O
文件系统把持久化字节映射为名称、元数据和保护规则。设计必须规定分配、缓存、一致性、崩溃恢复和并发语义。文件描述符是进程拥有的间接引用,它可以指向普通文件、目录、管道、套接字或设备。统一句柄模型让应用可以组合I/O操作,而不必了解每种设备协议。

图5:存储层次;通常越快的层容量越小,容量越大的层访问延迟越高。
|
概念 |
目的 |
实现关注点 |
正确性问题 |
|
命名 |
把人类可读名称映射到对象 |
目录、挂载点、命名空间 |
多个名称能否指向同一对象 |
|
元数据 |
记录所有者、大小和时间戳 |
inode或文件记录 |
更新如何保持原子性 |
|
分配 |
将文件块放置到介质 |
区段、空闲空间图 |
碎片化如何处理 |
|
缓存 |
减少慢速设备的重复访问 |
页缓存、写回 |
何时认为数据已持久化 |
|
日志 |
在结构更新前记录意图 |
元数据或全数据日志 |
崩溃恢复有哪些状态 |
表5:文件系统概念及其正确性问题。
页缓存经常让普通文件I/O看起来比底层存储更快,因为读操作可能直接由内存提供,写操作也可能延迟执行。因此,“持久化”是语义问题:一次成功写入可能只表示数据进入内核缓冲区、设备队列,或者已经能够抵抗断电,具体取决于API和硬件。fsync等同步操作表达了更强要求,但其成本和精确保证必须结合所用文件系统和设备栈理解。
5.1 设备驱动与异步I/O
驱动程序把操作系统抽象转换为设备特定命令。中断通知CPU发生了事件,直接内存访问(DMA)允许设备传输数据而不必让CPU逐字节复制。现代高性能I/O使用批处理、轮询、完成队列和零拷贝路径降低每次操作的开销。这些优化使顺序和缓冲区所有权更复杂,因此接口必须明确内存何时可以复用,以及哪些屏障可以保证设备看到一致状态。
- 区分提交完成与持久化完成。
- 在异步边界上明确缓冲区生命周期和所有权。
- 除带宽外,还要观测队列深度、服务时间、尾延迟、重试和错误恢复。
6. 保护、安全、网络与可靠性
保护机制控制主体(例如进程)如何访问客体(例如文件、页面、设备和套接字)。硬件特权级区分内核执行和用户执行;页面权限阻止不应有的读、写和执行;系统调用校验可以避免不可信参数破坏内核。访问控制列表、能力模型、沙箱和强制策略提供了不同的授权表达方式。重要的安全属性是:权限显式、可审查,并且难以被意外放大。
网络把操作系统抽象扩展到多台机器。套接字提供端点,协议栈处理成帧、寻址、重传、拥塞控制和排序。可靠字节流并不等价于应用级事务已经持久化或可安全重试。因此,分布式系统还需要超时、重试、请求标识、租约以及明确的失败处理语义。操作系统提供机制,应用协议必须定义业务语义。
6.1 可靠性与可观测性
可靠系统假设故障一定会发生:进程会崩溃,设备会返回错误,链路会重排数据包,时钟会漂移,资源会耗尽。恢复设计包括检查点、日志、复制、重启监督和优雅降级。可观测性应通过日志、指标、追踪、性能分析和资源计数器把症状连接到机制。单独的CPU使用率不是诊断;当它与运行队列、缓存缺失、I/O等待、锁竞争和请求延迟相关联时才有意义。
- 授权失败时应默认拒绝;可选依赖故障时应尽量优雅降级。
- 配置、密钥和更新机制也属于可信计算基的一部分。
- 采用纵深防御:隔离、校验、最小权限、监控和恢复相互强化。
- 主动测试崩溃一致性和降级模式,不要等生产故障暴露问题。
7. 实用分析清单
分析一个操作系统特性时,应先明确抽象及其契约,再识别涉及的资源、特权转换、并发模型、故障模式和可观测信号。随后追问过载、取消、部分失败、重启和恶意输入下会发生什么。这种方法比记忆具体命令更持久,因为它同样适用于内核、运行时、虚拟机管理器、容器平台和分布式服务。
|
问题 |
重要性 |
应收集的证据 |
|
抽象是什么? |
明确契约,隐藏无关实现细节 |
API、不变量、所有权规则 |
|
每项资源由谁拥有? |
避免泄漏、竞态和代理混淆 |
生命周期追踪、句柄、配额 |
|
哪些操作会阻塞或失败? |
暴露死锁和无界尾延迟 |
等待图、超时、错误路径 |
|
恢复点在哪里? |
决定持久化和重启行为 |
日志、检查点、重放测试 |
|
如何测量? |
把直觉与证据区分开 |
计数器、追踪、负载和置信区间 |
表6:操作系统设计与故障排查的通用分析清单。
结论:操作系统本质上是协调引擎。抽象、保护、并发控制、资源计费、故障恢复和测量是其持久原则。硬件会不断变化,但这些原则仍然指导着内核、云平台、容器、边缘系统和专用加速器。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)