訊號 是 Linux 進程間最基本的非同步通知機制。想像核心是大樓管理員,進程是住戶,訊號就是塞進信箱的小紙條。本文從核心視角解析訊號生命週期、常見訊號用途、Shell 操作實戰與自訂處理邏輯。
kill(), sigqueue()) 將訊號放入目標進程的 signal 位圖 (struct task_struct->pending)。Pending 狀態,直到進程從核心態返回用戶態 (系統呼叫結束、中斷返回、排程器切換) 時檢查並處理。sigprocmask() 將特定訊號加入 blocked 集合,訊號持續 Pending 直到解除阻塞。| 訊號 | 編號 | 來源/觸發 | 預設動作 | 典型用途 |
|---|---|---|---|---|
| SIGHUP | 1 | 終端機掛斷 / 進程組長退出 | 終止 | 通知服務重讀配置 |
| SIGINT | 2 | Ctrl+C | 終止 | 互動式中斷前景程式 |
| SIGQUIT | 3 | Ctrl+\ | 終止 + Core Dump | 強制退出並留核心檔除錯 |
| SIGILL | 4 | 非法指令 | 終止 + Core | 程式錯誤/編譯不匹配 |
| SIGTRAP | 5 | 斷點/陷阱指令 | 終止 + Core | 除錯器斷點 |
| SIGABRT | 6 | abort() | 終止 + Core | 程式自我終止 |
| SIGFPE | 8 | 算術例外 (除零、溢位) | 終止 + Core | 數值運算錯誤 |
| SIGKILL | 9 | kill -9 | **立即終止 (不可捕捉/阻塞/忽略)** | 最後手段強制殺程序 |
| SIGSEGV | 11 | 記憶體非法存取 | 終止 + Core | Segmentation Fault |
| SIGPIPE | 13 | 寫入無讀端管線 | 終止 | 忽略它並檢查 write 回傳 EPIPE |
| SIGALRM | 14 | alarm(), setitimer() | 終止 | 定時器/超時控制 |
| SIGTERM | 15 | kill (預設) | 終止 | 優雅關閉 (可捕捉清理資源) |
| SIGCHLD | 17 | 子進程結束/停止 | 忽略 | 父進程 wait() 回收 |
| SIGCONT | 18 | kill -CONT | 繼續執行 | 恢復被停止的進程 |
| SIGSTOP | 19 | kill -STOP | **停止 (不可捕捉/阻塞/忽略)** | 暫停進程 |
| SIGTSTP | 20 | Ctrl+Z | 停止 | 互動式暫停前景程式 |
| SIGTTIN/SIGTTOU | 21/22 | 後台進程讀/寫終端機 | 停止 | 作業控制 |
| SIGUSR1/2 | 10/12 | 用戶自訂 | 終止 | 應用層自定義協議 |
完整列表:man 7 signal 或 kill -l。
# 1. 啟動前景程式
ping localhost
# 2. Ctrl+Z 發送 SIGTSTP → 暫停
^Z
[1]+ Stopped ping localhost
# 3. 查詢 PID
ps -C ping -o pid=
# 27397
# 4. 發送 SIGCONT 恢復 (背景繼續)
kill -CONT 27397
# 或 fg %1 (前景恢復)
# 5. 發送 SIGTERM 優雅結束
kill -TERM 27397
# 6. 強制殺死
kill -KILL 27397 # 或 kill -9
# C 語言範例 #include #include #include void handler(int sig) { printf("Caught signal %d\n", sig); } int main() { // 1. 忽略 signal(SIGINT, SIG_IGN); // 2. 預設動作 signal(SIGTERM, SIG_DFL); // 3. 自訂處理器 (捕捉) signal(SIGUSR1, handler); // 或更安全的 sigaction() struct sigaction sa = { .sa_handler = handler, .sa_flags = SA_RESTART }; sigaction(SIGUSR2, &sa, NULL); while(1) pause(); // 等待訊號 return 0; }
SA_RESTART:讓被中斷的系統呼叫 (如 read()) 自動重啟,避免 EINTR。trap 'cmd' SIG:Shell 腳本捕捉訊號 (清理暫存檔、優雅關閉)。nohup 實作原理:忽略 SIGHUP + 重導向輸出。systemd 服務關閉順序:SIGTERM → 等待 TimeoutStopSec → SIGKILL。