主题
17 · 进程:PID、父子关系与地址空间
目标:说清进程是什么,用
ps/pstree//proc看 PID、PPID 与地址空间入口。
命令行前置:05 · 进程端口;概念前置:16 · 系统调用。
1. 环境前提
bash
mkdir -p ~/lab/os
sudo apt install -y psmisc # 提供 pstree(若尚未安装)1
2
2
2. 概念框(轻量课本)
| 词 | 一句话 |
|---|---|
| 进程 | 正在运行的程序实例:有独立的 PID、内存视图、打开的文件等 |
| PID / PPID | 进程号 / 父进程号 |
| fork | 复制出子进程(Linux 上实际常用 clone;心智上仍说 fork) |
| exec | 在当前进程里换成另一个可执行文件的镜像 |
| 地址空间 | 进程眼里的「虚拟内存地图」(用户代码、堆、栈、映射的库…) |
Shell 跑外部命令的典型路径:
text
shell ──fork──► 子进程 ──exec──► ls(覆盖子进程镜像)1
3. 动手:ps、pstree、/proc
bash
echo "我的 PID=$$ 父 PID=$PPID"
ps -o pid,ppid,user,stat,cmd -p $$
pstree -p $$
# 当前 shell 在 /proc 里的名片
ls /proc/$$
cat /proc/$$/status | head -n 20
cat /proc/$$/cmdline | tr '\0' ' '; echo1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
/proc/PID/ 常用文件:
| 路径 | 含义 |
|---|---|
status | 可读摘要(Name、State、PPid、VmRSS…) |
cmdline | 启动命令行(\0 分隔) |
cwd / exe | 工作目录 / 可执行文件(符号链接) |
fd/ | 打开的文件描述符(21 篇) |
maps | 虚拟内存映射(19 篇) |
观察父子:
bash
bash -c 'echo child=$$ parent=$PPID; sleep 2' &
sleep 0.2
pstree -p $$
wait1
2
3
4
2
3
4
极短「假 fork」演示(Bash 后台任务):
bash
cat > ~/lab/os/child-demo.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
echo "child pid=$$ ppid=$PPID"
sleep 3
EOF
chmod 755 ~/lab/os/child-demo.sh
~/lab/os/child-demo.sh &
CHILD=$!
echo "parent=$$ started child=$CHILD"
ps -o pid,ppid,cmd -p "$$,$CHILD"
wait1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
4. 与命令行篇对照
| 05 里你会 | OS 视角 |
|---|---|
ps aux | 枚举进程控制块(PCB)的用户可读视图 |
kill PID | 向进程发信号(23 篇) |
htop | 实时看调度与资源(18、19) |
5. 动手清单
- [ ] 写出当前 shell 的 PID、PPID
- [ ]
pstree -p $$看清父子树 - [ ] 打开
/proc/$$/status,指出Name与PPid - [ ] 跑
child-demo.sh,确认子进程 PPID 是你的 shell
6. 常见翻车
| 翻车 | 处理 |
|---|---|
/proc 里数字太多 | 只盯自己的 $$ 或 pgrep 到的 PID |
僵尸进程 Z | 父进程未 wait;练习机重启或结束父进程即可体会 |
| 把「线程」和「进程」混为一谈 | 18 篇专门拆 |
7. 官方 / 延伸
man ps、man pstree、man 5 proc- proc(5)
下一篇:线程、调度与上下文切换。
