跳到内容

第 0 卷 / 第 1 章 / 第 5 课

1.5 探索你的系统(实验) ​

前置知识:程序、进程、线程和内存的基本模型

预计时间:15–25 分钟

完成标志:能启动、观察并清理一个测试进程,读懂本机的 CPU 和内存概况

现在独立检查这台机器。整段实验只操作你亲手创建的进程和临时目录;看见陌生 PID 时不要碰它。

第 1 步:记录平台与工具 ​

Linux:

bash
uname -a
command -v ps free python3

macOS:

bash
sw_vers
command -v ps vm_stat python3

Windows PowerShell:

powershell
$PSVersionTable.PSVersion
Get-Command Get-Process,python

类型: runnable观察: 命令路径和版本决定后续字段是否可用。缺少 Python 时先停止,不要把安装步骤混进本实验。

第 2 步:查看 CPU 和内存 ​

Linux:

bash
lscpu | sed -n '1,12p'
free -h

macOS:

bash
sysctl -n machdep.cpu.brand_string
sysctl -n hw.logicalcpu
vm_stat

Windows PowerShell:

powershell
Get-CimInstance Win32_Processor | Select-Object Name,NumberOfCores,NumberOfLogicalProcessors
Get-CimInstance Win32_OperatingSystem | Select-Object TotalVisibleMemorySize,FreePhysicalMemory

记录逻辑 CPU 数。内存字段的单位和定义因平台而异,不要直接比较表中的原始数字。

第 3 步:启动、观察和清理 ​

Bash:

bash
python3 -c 'import time; time.sleep(30)' &
pid=$!
ps -p "$pid" -o pid,ppid,stat,%cpu,%mem,etime,command
kill "$pid"
wait "$pid" 2>/dev/null || true
if ps -p "$pid" >/dev/null 2>&1; then
  echo "cleanup failed: PID $pid still exists" >&2
  exit 1
fi
echo "cleanup complete"

PowerShell:

powershell
$process = Start-Process python -ArgumentList '-c "import time;time.sleep(30)"' -PassThru
Get-Process -Id $process.Id
Stop-Process -Id $process.Id
$process.WaitForExit()
"cleanup complete"

类型: runnable观察: Bash 输出包含测试 PID、父进程、状态和运行时间;PowerShell 的 Get-Process 默认列不同,可另外用 Get-CimInstance Win32_Process -Filter "ProcessId = $($process.Id)" 在停止前查看 ParentProcessId。两组命令最后都应看到 cleanup complete。PID 退出后可能很快被其他进程复用,所以清理判断只适合紧接实验执行。

第 4 步:可选端口实验 ​

Linux 可在临时目录启动本地 HTTP 服务,只监听回环地址。把下面内容保存为 explore-port.sh,再运行 bash explore-port.sh;独立脚本退出时才能触发这里的退出清理:

bash
set -e
workdir=$(mktemp -d)
server_pid=
cleanup() {
  if [[ -n "$server_pid" ]]; then
    kill "$server_pid" 2>/dev/null || true
    wait "$server_pid" 2>/dev/null || true
  fi
  rm -r -- "$workdir"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

printf 'atlas\n' > "$workdir/index.html"
port=$(python3 -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()')
python3 -m http.server "$port" --bind 127.0.0.1 --directory "$workdir" >"$workdir/http.log" 2>&1 &
server_pid=$!
sleep 1
if ! kill -0 "$server_pid" 2>/dev/null; then
  sed -n '1,20p' "$workdir/http.log" >&2
  exit 1
fi
curl -fsS "http://127.0.0.1:$port/"
ss -ltnp "sport = :$port" || true

类型: runnable环境: Linux、Bash、Python 3、curl、ss 观察: Python 先申请一个当时空闲的回环端口;curl 输出 atlas,ss 显示 127.0.0.1 上的监听者。申请端口与启动服务之间仍有很小的竞争窗口,失败时脚本会先打印日志。正常退出或脚本因命令失败退出时,EXIT trap 回收资源;收到 INT、TERM 时先以对应状态退出,再清理。SIGKILL 无法捕获,强制结束后需要手动检查残留资源。这个服务器只用于本机实验,不适合生产环境。

排障顺序 ​

  1. command -v 或 Get-Command 是否找到程序?
  2. 错误来自命令语法、权限、缺少工具还是端口占用?
  3. 测试进程是否仍存在?先按保存的 PID 清理。
  4. 你的输出与示例不同,是平台差异还是模型错误?记录具体字段再判断。

验收 ​

实验结束时,至少留下四条可核对的记录:逻辑 CPU 数、测试进程的 PID 与 PPID、一张进程状态快照,以及清理成功的输出。再检查测试进程和临时目录已经消失。这里看重证据,不看输出是否与截图一模一样。

确认测试进程和临时目录已清理。继续阅读:终端入门,我们会把刚才用过的命令、参数和路径逐一拆开。

参考资料 ​

Built with VitePress | Software Systems Atlas