🧠 第 1 章 · I/O 基础知识

用户态 / 内核态切换 · 文件描述符 · read() 系统调用流水线 · 系统调用代价

① 用户态 ↔ 内核态切换动画

点击下面按钮,模拟一次系统调用 read(),观察 CPU 在两个 ring 之间穿越的全过程。

🧑 用户态(Ring 3)
你的程序运行的地方 · 不能直接操作硬件
🛡️ 内核态(Ring 0)
Linux 内核 · 可访问全部硬件与内存
🤖
⬇️
⬆️
→ 点击按钮开始

② 文件描述符表交互演示

点击「open / socket / epoll_create」分配新的 fd,点击具体的 fd 卡片可以查看它指向的资源。注意 fd 0/1/2 是进程启动时自动有的。

→ 点击 fd 卡片查看详情

③ read() 系统调用的两阶段流水线

一次 read() 永远经历「等数据」+「拷数据」两个阶段。这是后续区分 I/O 模型的根基。

📞

① 用户调 read()

陷入内核态

② 等数据到达

网卡 → 内核缓冲区
📦

③ 拷数据到用户

内核 → 用户 buf
→ 选择 I/O 模型开始演示

④ 系统调用开销直观对比

系统调用比函数调用慢得多——这就是为什么 epoll 要"批量减少 syscall 次数"。拖动滑块看不同操作的开销对比。

💡 数据来源:典型 x86_64 服务器实测平均值。可以看到——「批量 read 1KB」比「每字节调用一次 read」快了几个数量级,这就是系统调用要尽量批量化的根本原因。