承接進程管理核心體系,本文深入 kill 信號語義、僵屍/孤兒進程產生與清理機制、top 互動熱鍵、jobs/fg/bg 作業控制,並提供實戰排查腳本。
| 信號 | 編號 | 名稱 | 預設動作 | 可捕獲 | 典型用途 |
|---|---|---|---|---|---|
| SIGHUP | 1 | Hang Up | Term | Y | Daemon 重載配置 |
| SIGINT | 2 | Interrupt | Term | Y | Ctrl+C 終止前台 |
| SIGQUIT | 3 | Quit | Core+Term | Y | Ctrl+\ 產生 core |
| SIGILL | 4 | Illegal Instr | Core+Term | Y | 二進制損壞 |
| SIGTRAP | 5 | Trace Trap | Core+Term | Y | Debugger 斷點 |
| SIGABRT | 6 | Abort | Core+Term | Y | abort()、assert 失敗 |
| SIGBUS | 7 | Bus Error | Core+Term | Y | 記憶體對齊錯誤 |
| SIGFPE | 8 | Float Exception | Core+Term | Y | 除零、溢位 |
| SIGKILL | 9 | Kill | Term | N | **最後手段,不可捕獲** |
| SIGUSR1 | 10 | User 1 | Term | Y | 自定義(如重開日誌) |
| SIGSEGV | 11 | Seg Fault | Core+Term | Y | 記憶體非法訪問 |
| SIGUSR2 | 12 | User 2 | Term | Y | 自定義 |
| SIGPIPE | 13 | Broken Pipe | Term | Y | 寫無讀端管道 |
| SIGALRM | 14 | Alarm | Term | Y | alarm() 定時器 |
| SIGTERM | 15 | Terminate | Term | Y | 優雅關閉(systemd 預設) |
| SIGSTKFLT | 16 | Stack Fault | Term | Y | 协處理器錯誤 |
| SIGCHLD | 17 | Child Status | Ign | Y | 子進程退出/停止 |
| SIGCONT | 18 | Continue | Cont | Y | 恢復 SIGSTOP |
| SIGSTOP | 19 | Stop | Stop | N | **不可捕獲,強制暫停** |
| SIGTSTP | 20 | Terminal Stop | Stop | Y | Ctrl+Z |
| SIGTTIN | 21 | TTY In | Stop | Y | 後台讀終端 |
| SIGTTOU | 22 | TTY Out | Stop | Y | 後台寫終端 |
| SIGURG | 23 | Urgent Data | Ign | Y | Socket OOB 資料 |
| SIGXCPU | 24 | CPU Limit | Core+Term | Y | 超過 CPU 時間限制 |
| SIGXFSZ | 25 | File Size Limit | Core+Term | Y | 超過檔案大小限制 |
| SIGVTALRM | 26 | Virtual Alarm | Term | Y | 虛擬時間定時器 |
| SIGPROF | 27 | Profile Alarm | Term | Y | 剖析定時器 |
| SIGWINCH | 28 | Window Change | Ign | Y | 終端視窗大小變化 |
| SIGIO | 29 | I/O Possible | Term | Y | 非同步 I/O 就緒 |
| SIGPWR | 30 | Power Fail | Term | Y | 電源異常 |
| SIGSYS | 31 | Bad Syscall | Core+Term | Y | 非法系統呼叫 |
exit(),父進程未 wait()/waitpid() 回收退出碼ps 顯示 Z、佔用 PID、task_struct 殘留、不佔 CPU/記憶體/proc/sys/kernel/pid_max(預設 32768),導致無法建新進程SIGCHLD handler + waitpid(-1, NULL, WNOHANG)wait() 清理echo 1 > /proc/sys/kernel/ns_last_pid 無效,需重啟或修復代碼init (PID 1) 或 systemd (PID 1) 收養,getppid() 返回 1| 鍵 | 功能 | 記憶口訣 |
|---|---|---|
P | 按 %CPU 排序 | Processor |
M | 按 %MEM 排序 | Memory |
T | 按 TIME+ 排序 | Time |
1 | 切換顯示各 CPU 核心 | 1 core |
H | 切換顯示執行緒 | Threads |
c | 切換完整命令列 | Command |
u | 篩選用戶 | User |
k | 殺進程(輸入 PID、信號) | Kill |
r | 改 nice 值 | Renice |
d | 改刷新間隔 | Delay |
W | 寫入配置 ~/.toprc | Write |
q | 退出 | Quit |
# 啟動前台任務
sleep 100
# Ctrl+Z → 暫停並放入後台 [1]+ Stopped sleep 100
# 後台繼續
bg %1
# [1]+ sleep 100 &
# 查看作業
jobs -l
# [1]+ 12345 Running sleep 100 &
# 切回前台
fg %1
# sleep 100
# 直接後台啟動
sleep 100 &
# [1] 12345
# 終止作業
kill %1
# 或
kill 12345
#!/bin/bash
# proc_diag.sh — 進程健康快照
set -euo pipefail
echo "=== $(date) Process Diagnostics ==="
# 1. 僵屍進程
zombies=$(ps -eo stat,ppid,pid,cmd | awk '$1~/^Z/ {print $2, $3, $4}')
if [ -n "$zombies" ]; then
echo "⚠ ZOMBIES FOUND:"
echo "$zombies"
echo "Parent PIDs to fix: $(echo "$zombies" | awk '{print $1}' | sort -u)"
else
echo "✓ No zombies"
fi
# 2. D 狀態進程
dstate=$(ps -eo stat,pid,cmd | awk '$1~/^D/ {print $2, $3}')
if [ -n "$dstate" ]; then
echo "⚠ D STATE (uninterruptible sleep):"
echo "$dstate"
for pid in $(echo "$dstate" | awk '{print $1}'); do
echo " Stack for $pid:"
cat /proc/$pid/stack 2>/dev/null | head -5
done
else
echo "✓ No D state processes"
fi
# 3. 高 CPU 進程
echo "Top 5 CPU:"
ps -eo pcpu,pid,user,cmd --sort=-pcpu | head -6
# 4. 高記憶體進程
echo "Top 5 MEM:"
ps -eo pmem,pid,user,cmd --sort=-pmem | head -6
# 5. 開啟檔案數最多進程
echo "Top 5 open files:"
for pid in $(ps -eo pid | tail -n +2); do
cnt=$(ls -1 /proc/$pid/fd 2>/dev/null | wc -l)
echo "$cnt $pid"
done | sort -rn | head -5
echo "=== Done ==="
結語: 信號是進程的「神經系統」,僵屍是「未完成的告別」,top 是「動態 MRI」,作業控制是「Shell 的任務管理器」。把這些串起來,你就能在幾分鐘內完成從「現象」到「根因」到「修復」的閉環。