符号、命令与代码约定
本书的排版语言刻意保持少而稳定。读之前花三分钟认一遍,后面就不会被盒子、提示符和版本标签打断。
1. 语义盒
正文用八种盒子区分「这是什么性质的内容」。盒子可以嵌套 proof/sol,但不嵌套同类盒子。
| 盒子 | 用途 | 读法 |
|---|---|---|
::: def | 定义、结构、接口语义 | 必记骨架 |
::: thm | 定理、定律、可证明的结论 | 记住条件与结论 |
::: ex | 例题、手算、代码走查 | 先自己做,再看解 |
::: intuition | 白话解释「这条在讲什么」 | 卡住时先读它 |
::: method | 流程、清单、排障步骤 | 照着做 |
::: errata | 常见误解、陷阱、版本差异 | 每节至少看一遍 |
::: think | 辨析、开放问题、设计取舍 | 二刷再想 |
::: note | 边注、延伸、历史 | 可跳 |
::: proof | 推导与证明(可折叠) | 第一遍可跳 |
::: sol | 习题/自测答案(可折叠) | 做完再展开 |
写法:
::: def 定义 2.2.1 · 文件描述符 {#def-2.2.1}
文件描述符是进程文件描述符表中一个非负整数下标……
:::
优先级标记写在类型后:::: thm[skip] ...。core 必读、main 默认、skip 第一遍可跳。
2. 终端与代码
2.1 终端会话
带窗口标题的深色块是真实终端会话;$ 是普通用户,# 是 root。输出行不带提示符。
$ id -u
1000
$ sudo -i
# id -u
0
本书不写 $ sudo 与 # 混用的伪会话:要么整段普通用户 + sudo,要么整段 root。
2.2 代码
- 语言以 C17 + POSIX.1-2008 为主;内核代码以 Linux 6.8 为准(C11/GNU11)。
- 用户态示例默认编译命令:
cc -std=c17 -D_GNU_SOURCE -Wall -Wextra -Werror -O2 -g prog.c -o prog
- 需要 pthread 时加
-pthread;需要实时库时加-lrt(新 glibc 已并入 libc,但保留不报错)。 - 示例省略
#include时,会在同页的「编译」块列出所需头文件。 - 错误处理不省略:
errExit()、errMsg()是本书自定义的薄封装,定义见 2.1 节。 - 内核代码片段标注文件与函数,例如
kernel/fork.c: kernel_clone();省略号表示与主题无关的代码。
2.3 命令块
# 注释:这条命令在做什么
ss -lntp | grep :8080
- 行首
#在 bash 代码块里是注释;在 terminal 块里是 root 提示符。看块的外观区分。 - 可复制的多行命令用
\续行,不把提示符写进代码块。 - 输出中的
<...>是占位符,实际执行时替换。
3. 编号与引用
- 章号:
2.2表示第 2 篇第 2 章;节号:2.2.3;图号:图 2.2-3;表号:表 2.2-1。 - 盒子编号与节号一致:
定义 2.2.1是 2.2 节第 1 个定义。 - 交叉引用写作
[定义 2.2.1](part2/ch02.md#def-2.2.1);正文里也可以写[@def-2.2.1],由预处理器解析。 - 锚点命名:
def-<节号>.<序号>、thm-...、fig-...、sec-...。全书唯一。
4. 版本与证据标签
正文中的版本标注有三种:
| 写法 | 含义 |
|---|---|
Linux 6.8 | 在该版本源码/环境验证过 |
Linux 6.6+ | 该版本起成立,之前可能不同 |
glibc 2.39 | 与 libc 实现相关 |
证据强度在正文中直接写清:「POSIX 规定」「man-pages 说」「实测」「工程惯例」。没有标注的,默认是当前基线下的实现行为,换版本要复核。
5. 单位与缩写
| 写法 | 含义 |
|---|---|
KiB/MiB/GiB | 1024 进制(内存、页) |
KB/MB/GB | 1000 进制(磁盘厂商标称) |
b/B | bit / Byte;网络速率用 Mbps,存储用 MB/s |
fd | file descriptor |
PCB | process control block(Linux 里是 task_struct) |
VA/PA | virtual/physical address |
MMU/TLB | 内存管理单元 / 地址转换缓存 |
ISR | interrupt service routine |
NAPI | New API,Linux 网卡收包轮询机制 |
RCU | Read-Copy-Update |
COW | copy-on-write |
VFS | virtual file system |
IPC | inter-process communication |
6. 退出码与错误
- 用户态程序:成功
0,失败非0;本书示例统一用EXIT_FAILURE。 - Shell:
$?是上一条命令的退出码;set -e下非零会退出,但if/&&/||的语境例外。 - 系统调用失败返回
-1并设置errno;成功也可能返回 0,不能只用返回值判断。 - 常见错误码:
EINTR(被信号打断)、EAGAIN(非阻塞暂无数据)、EACCES(权限)、ENOENT(不存在)、EEXIST(已存在)、ENOSPC(空间不足)、EMFILE/ENFILE(fd 耗尽)。
7. 路径与源码
- 用户态路径以
/开头;内核源码路径相对源码根,如mm/memory.c。 - 本书用 Linux 6.8 的源码布局;4.x/5.x 的函数名差异在正文标注(如
do_fork()→kernel_clone())。 - 结构体字段只列与主题相关的;省略字段用
/* ... */。
8. 图形语言
- 所有 SVG 图有
<title>、<desc>与图注;图注以「读图:」开头,告诉你先看哪条线。 - 时序图从上到下是时间,从左到右是参与者;实线是调用/数据,虚线是返回/异步。
- 状态图的双线圆是终态;自环表示不改变状态的事件。
- 地址布局图从低地址到高地址自上而下;标
▲的是增长方向。
9. 与母本的对应
每章末尾的「母本对应」用下表格式;完整矩阵在附录 A.4。
| 母本 | 章节 | 本书落点 | 程度 |
|---|---|---|---|
| Kerrisk | 4–5 | 2.2–2.3 | 完整 |
| CSAPP | 9 | 1.9 + 3.8 | 理论 + 实现 |
下一站:实验环境把工具装好;后面的命令都假设你已经有一台可折腾的 Linux。