跳转至

Ch13 §03 操作系统 · 讲解稿

章节定位: Ch13 系统软件。教"OS 如何管理硬件": 进程/线程 / 虚拟内存 / 文件系统 / 调度 / 死锁。 承接: §02 硬件 → §03 OS 作为"硬件管家" 走向: §04 并发 (用多进程/线程) / §05 编程语言 篇幅: ~4200 字 / 阅读 12 分钟 / 讲解 25-30 分钟


一 · 一句话总览

操作系统 = 硬件与应用之间的"中间人": 进程 (运行单位) / 内存 (虚拟化) / 文件 (持久化) / 调度 (CPU 分配) / 死锁 (并发陷阱)。Linux 是 AI 工程师的事实标准。


二 · 心智模型

OS 像物业管理: - 进程: 住户 - 内存: 房间 - CPU: 公共设施 (轮流用) - 文件系统: 仓库 - 调度员: 决定谁用什么


三 · 章节主线 (5 段)

第 1 段 · 进程与线程 (10 分钟)

3.1.1 进程 (Process)

进程 = 一次程序的执行。有独立的地址空间 (~几 GB 虚拟内存)。

ps -ef  # 查看进程
top     # 动态查看

PCB (Process Control Block) 存: PID, 状态, 寄存器, 内存指针, IO 信息。

3.1.2 进程状态机

       新建
        ↓
      就绪 ←─────→ 运行
        ↓         ↑
       阻塞        |
        ↓         |
       退出
  • 新建: 刚创建
  • 就绪: 等待 CPU
  • 运行: 占用 CPU
  • 阻塞: 等待 IO
  • 退出: 终止

3.1.3 线程 (Thread)

线程 = 进程内的执行流。共享地址空间, 独立栈 (1 MB)。

import threading

def worker(name):
    print(f"Worker {name}")

t = threading.Thread(target=worker, args=("A",))
t.start()
t.join()

3.1.4 进程 vs 线程

维度 进程 线程
内存 独立 共享
创建 重 (~10 ms) 轻 (~10 μs)
通信 IPC (难) 共享变量 (易但需同步)
崩溃影响 单进程 全线程

3.1.5 fork vs exec

import os
pid = os.fork()
if pid == 0:
    # 子进程
    os.execvp("ls", ["ls", "-l"])
else:
    # 父进程
    os.waitpid(pid, 0)
  • fork: 复制当前进程 (Code+Data)
  • exec: 替换为新程序

第 2 段 · 虚拟内存 (10 分钟)

3.2.1 虚拟地址 vs 物理地址

程序用虚拟地址 (进程独立视角), CPU 通过 MMU 翻译为物理地址。

虚拟地址 → MMU → 物理地址
   VA          PA

3.2.2 分页

  • 内存分成固定大小页 (4 KB 典型)
  • 虚拟页 → 物理页 (页表映射)
  • 页表: 一项 = 4-8 字节
  • 32-bit VA + 4 KB 页 → 1M 页表项 → 4 MB 页表

3.2.3 TLB

Translation Lookaside Buffer: 页表的硬件缓存。

  • TLB 命中: ~1 ns
  • TLB miss: 查页表 ~100 ns
  • Page fault: 磁盘换入 ~10 ms

3.2.4 进程地址空间

0xFFFFFFFF  ┌────────────┐
            │  内核区    │ (操作系统)
            ├────────────┤
            │  栈 ↓     │ (函数调用, 局部变量)
            │     ⋮     │
            │  堆 ↑     │ (malloc/new)
            ├────────────┤
            │  BSS      │ (未初始化全局)
            │  数据段   │ (已初始化全局)
            │  代码段   │ (text)
0x00000000  └────────────┘

3.2.5 内存映射

import mmap

# 把文件映射到内存
with open('data.bin', 'rb') as f:
    with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
        data = m[:100]  # 直接读, 无 read() 系统调用

3.2.6 案例: vLLM PagedAttention

LLM 推理用 KV cache 存中间结果。显存有限, KV cache 大小不一, 浪费严重。

PagedAttention (vLLM, SOSP 2023): 像 OS 虚拟内存一样把 KV cache 分页, 减少碎片, 提升 4-24× 吞吐。


第 3 段 · 调度与死锁 (8 分钟)

3.3.1 调度算法

算法 思路 优缺点
FCFS 先来先服务 简单, 长作业卡短作业
SJF 短作业优先 最佳平均周转, 但饥饿
RR 时间片轮转 公平, 但切换开销
CFS Linux 完全公平 红黑树, \(O(\log n)\)
EDF 最早截止优先 实时系统

3.3.2 死锁四条件

  1. 互斥: 资源独占
  2. 占有并等待: 持有 + 等
  3. 不剥夺: 不能强制释放
  4. 循环等待: 环路

打破任一即可。

3.3.3 避免死锁: 银行家算法

预先分配前, 检查是否安全 (无环)。

实用方案: 资源排序 + 一次性申请。

3.3.4 Python GIL

# GIL (Global Interpreter Lock): 同一时刻只有一个线程执行 Python 字节码
# 多线程对 IO 密集任务有效 (释放 GIL), 但 CPU 密集任务无效

绕过 GIL: multiprocessing, numpy 内置并行, Cython, nogil Python 3.13+。


第 4 段 · 文件系统 (8 分钟)

3.4.1 文件系统结构

  • 引导块 (boot)
  • 超级块 (superblock): 文件系统元数据
  • inode 表: 每个文件一个 inode, 存元数据
  • 数据块: 实际内容

3.4.2 inode

ls -i file.txt  # 显示 inode 号
stat file.txt   # 显示 inode 详情

inode = 256 字节, 存: 权限, 大小, 时间戳, 数据块指针 (12 直接 + 1 间接 + 1 双间接 + 1 三间接)。

3.4.3 常见 FS

FS 特点
ext4 Linux 默认
XFS 大文件, 高性能
Btrfs CoW, 快照
ZFS Solaris, 数据完整性
NFS 网络文件系统
HDFS Hadoop 分布式

3.4.4 数据湖与 LLM

LLM 训练数据存于: - S3 / GCS (对象存储) - HDFS / Ceph (分布式 FS) - 本地 NVMe (高速训练)

读取: mmap / 直接 IO / 异步。


第 5 段 · 中断与系统调用 (5 分钟)

3.5.1 系统调用

用户态 → 内核态的入口。

import os
# Python os.fork 是 wrapper, 实际调用 fork 系统调用
pid = os.fork()

常用: open, read, write, fork, exec, wait, mmap, ioctl, socket。

3.5.2 中断 vs 异常

类型 触发 例子
中断 (IRQ) 异步, 外设 键盘, 网卡
异常 同步, 程序 除零, 缺页
陷阱 (syscall) 同步, 主动 write

3.5.3 上下文切换

进程切换保存: 寄存器, 程序计数器, 栈指针, 内存映射。

开销: ~1-10 μs。Linux 用 TLB shootdown 优化。


四 · 易错点 (5 条)

  1. 进程 vs 线程: 多线程不一定快, GIL 下 Python 多线程对 CPU 任务无效。
  2. 虚拟地址 ≠ 物理地址: 程序永远只看到 VA。
  3. 死锁必要条件: 满足不一定会死锁, 但不满足一定不死。
  4. Page fault 慢: ms 级, 应避免。
  5. inode ≠ 文件名: 文件名 → inode → 数据。

五 · 跨章连接

章节 关联
Ch07 §04 Transformer LLM 推理 KV cache 类似 OS 页表
Ch08 §04 Diffusion 数据加载
Ch11 §05 VLA ROS OS
Ch14 §04 图算法 邻接表 = 文件存储

六 · 自测 5 题

  1. 进程 vs 线程差别?
  2. 虚拟内存如何工作?
  3. 死锁四条件?
  4. 调度算法 FCFS / RR / CFS?
  5. inode 存什么?

七 · 一句话总结

操作系统 = 硬件与应用之间的中间人。进程 (运行单位) / 虚拟内存 (VA↔PA) / 文件系统 (持久化) / 调度 (CPU 分配) / 死锁 (并发陷阱)。Linux 是 AI 工程师的事实标准 (vLLM / Docker / K8s 都跑在 Linux 上)。


八 · 板书建议

[板书 1: 进程状态机]
   新建 → 就绪 → 运行 → 阻塞 → 退出

[板书 2: 虚拟内存]
   VA → MMU → PA
   TLB 缓存页表

[板书 3: 地址空间]
   高位: 内核
        栈 ↓
        ⋮
        堆 ↑
        数据
   低位: 代码

[板书 4: 死锁]
   互斥 + 占有等待 + 不剥夺 + 循环
   打破任一即可

九 · 参考资料

  1. Tanenbaum, "Modern Operating Systems"
  2. Linux Man Pages (man 2 fork)
  3. vLLM PagedAttention 论文 (SOSP 2023)
  4. Ch02 §04 矩阵论 (本套书)
  5. Ch14 数据结构 (本套书)