操作系统

Book Notes · 02 · CSAPP

程序员视角的
操作系统边界

只记与 OS 直接相关的四章(异常控制流、虚存、系统 I/O、并发)。信息表示、机器级代码、处理器结构、存储层次见组成原理站 arch-site · CSAPP 组成侧。本页管机制原理;fork/exec/wait 与 fd 的接口语义深读见 APUE。口径以全书与图谱已校对文本为准。

08异常控制流

从程序员看得见的「突然换一条执行路径」反推内核入口:中断、异常、系统调用、信号、上下文切换。

四类异常

CSAPP 把异常(exception)分成四类:中断 interrupt、陷入 trap、故障 fault、终止 abort。异常是异常控制流的一种,后者还包含上下文切换、信号、非本地跳转等。处理程序都在内核态运行。系统调用是 trap 的典型实例,不是并列的第五类。中断/陷入返回下一条指令;故障修复后可能重执行当前指令,否则终止;终止不返回。中断与故障可能发生在用户态或内核态;不要把「从用户态进来」写成四类的共性。

正在执行→中断 / 陷入 / 故障 / 终止→内核处理→返回下一条 · 重执行 · 或不返回

进程接口

fork 在规范里要求逻辑复制地址空间;写时复制是常见实现,不是定义本身。exec 族成功则不返回,PID 不变。子进程退出后、被父进程 wait/waitpid 回收前才处于僵尸态。

易错:exit(3) 的括号是手册章节号,不是系统调用号。exit(3) 会跑 atexit 与 stdio 清理;_exit(2) 更直接;现代 glibc 的 _exit() 包装通常再进 exit_group(2)。

09虚拟内存

把每个进程的虚地址空间映射到有限物理页,并允许按需调入。

地址变换

VPN 查 TLB,未命中再查页表。P=1 表示已驻留,拼出物理地址。P=0 只是状态;访问合法页才缺页。非法地址走保护异常,不调页。

调入与置换

有空闲页框直接装入。无空闲才用 OPT / FIFO / LRU 等选牺牲页。FIFO 可能 Belady;OPT、LRU 作为栈算法不会。缺页过程中进程常阻塞,低级调度仍可让别人跑。

mmap

可以映射文件,也可以匿名映射。默认按需缺页;MAP_POPULATE 等可预取;文件页若已在 page cache 不必再读盘。

10系统级 I/O

Unix 把文件、管道、套接字都收成 fd。短读短写是合法现象。

描述符与偏移

fd 是该进程文件描述符表中的整数索引,指向系统打开文件表项。对可定位文件,read/write 按打开文件描述的偏移进行并更新它;管道、FIFO、套接字没有可定位偏移。

dup2

关闭并复用目标 fd 是系统调用内部的原子操作。oldfd 与 newfd 相同则不关闭,直接返回 newfd。不要在用户态先 close 再 dup 来「模拟」它。

12并发编程

进程、线程、I/O 复用是三条路。共享内存让数据竞争成为默认风险。

线程创建返回值

pthread_create 成功返回 0,失败返回错误号,线程标识经输出参数写回。不要把它和 clone 调用者「返回子 tid」混记。glibc 的 clone 包装让子任务从指定函数起步,并不从包装函数返回;raw clone 系统调用的子路径才返回 0。

同步

互斥锁保护临界区;条件变量用于等待某个谓词。并发是多个任务在重叠时间段推进:单核可交替,多核也可并行。并行是同一时刻实际同时执行。二者不是同义词。

易错:把多对一模型写成一对多。多个用户线程映射一个内核线程,才是多对一。

章末自测

不完全是。书中 exceptional control flow 覆盖中断、陷入、故障、终止。缺页是其中一类故障:合法页未驻留且本次访问发生。故障修复后可能重执行当前指令,否则终止。
子进程。父进程返回子 PID。失败则父进程得 -1,不创建子进程。
不是。应用必须检查实际返回值。仅当协议或目标要求收满指定长度时才循环补齐,并正确处理 EOF、错误及 EINTR/EAGAIN。普通 read 的一次短读本身可以就是本次有效结果。