这篇文章单独记录 Shell Lab。它对应 CSAPP 第 8 章,重点是进程、信号和 job control。
0. 目标
Shell Lab 通常要求实现一个简单 shell,支持:
- 运行前台任务
- 运行后台任务
jobsbgfgquit- 正确处理
SIGCHLD - 正确处理
SIGINT - 正确处理
SIGTSTP
1. 核心概念
需要先理解:
- 进程
- 子进程
- 进程组
- 前台任务
- 后台任务
- 信号
- zombie process
forkexecvewaitpid
2. Shell 的基本流程
一个极简 shell 大概是:
1 | while (1) { |
3. 信号处理
Shell Lab 的难点不在能不能 fork,而在信号。
重点:
- 子进程结束时,父进程会收到
SIGCHLD - 用户按 Ctrl-C,会产生
SIGINT - 用户按 Ctrl-Z,会产生
SIGTSTP - shell 自己不应该被随便杀掉
- 前台 job 应该收到终端信号
4. Job Control
job table 通常记录:
1 | job id |
常见状态:
1 | FG:前台运行 |
5. 嵌入式关联
Shell Lab 对嵌入式 Linux 很有价值:
- 理解服务进程如何启动子进程
- 理解信号和进程退出
- 理解 zombie process
- 理解 daemon / supervisor / shell 的基本模型
- 为调试 Linux 用户态程序打基础
6. 复盘重点
学完后要能回答:
fork后为什么会有两个返回值?execve之后原来的程序去哪了?- 为什么需要
waitpid回收子进程? - Ctrl-C 到底发给谁?
- 前台任务和后台任务有什么区别?
- 为什么信号处理里要注意竞态条件?