操作系统原理

从硬件抽象、进程、内存、存储到安全与虚拟化的系统性技术指南

图:操作系统抽象层次

本文为教学和工程参考资料。示意图中的数值为概念性示例,不代表特定内核或硬件的基准测试结果。

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:操作系统设计与故障排查的通用分析清单。

结论:操作系统本质上是协调引擎。抽象、保护、并发控制、资源计费、故障恢复和测量是其持久原则。硬件会不断变化,但这些原则仍然指导着内核、云平台、容器、边缘系统和专用加速器。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐