萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

Linux 訊號機制入門:產生、傳遞、處理與常見訊號實戰

訊號 是 Linux 進程間最基本的非同步通知機制。想像核心是大樓管理員,進程是住戶,訊號就是塞進信箱的小紙條。本文從核心視角解析訊號生命週期、常見訊號用途、Shell 操作實戰與自訂處理邏輯。

訊號生命週期

  1. 產生:核心 (硬體例外、定時器) 或進程 (kill(), sigqueue()) 將訊號放入目標進程的 signal 位圖 (struct task_struct->pending)。
  2. 等待:訊號處於 Pending 狀態,直到進程從核心態返回用戶態 (系統呼叫結束、中斷返回、排程器切換) 時檢查並處理。
  3. 傳遞:核心執行對應的 訊號處置。
  4. 阻塞:進程可用 sigprocmask() 將特定訊號加入 blocked 集合,訊號持續 Pending 直到解除阻塞。

常見訊號速查表

訊號編號來源/觸發預設動作典型用途
SIGHUP1終端機掛斷 / 進程組長退出終止通知服務重讀配置
SIGINT2Ctrl+C終止互動式中斷前景程式
SIGQUIT3Ctrl+\終止 + Core Dump強制退出並留核心檔除錯
SIGILL4非法指令終止 + Core程式錯誤/編譯不匹配
SIGTRAP5斷點/陷阱指令終止 + Core除錯器斷點
SIGABRT6abort()終止 + Core程式自我終止
SIGFPE8算術例外 (除零、溢位)終止 + Core數值運算錯誤
SIGKILL9kill -9**立即終止 (不可捕捉/阻塞/忽略)**最後手段強制殺程序
SIGSEGV11記憶體非法存取終止 + CoreSegmentation Fault
SIGPIPE13寫入無讀端管線終止忽略它並檢查 write 回傳 EPIPE
SIGALRM14alarm(), setitimer()終止定時器/超時控制
SIGTERM15kill (預設)終止優雅關閉 (可捕捉清理資源)
SIGCHLD17子進程結束/停止忽略父進程 wait() 回收
SIGCONT18kill -CONT繼續執行恢復被停止的進程
SIGSTOP19kill -STOP**停止 (不可捕捉/阻塞/忽略)**暫停進程
SIGTSTP20Ctrl+Z停止互動式暫停前景程式
SIGTTIN/SIGTTOU21/22後台進程讀/寫終端機停止作業控制
SIGUSR1/210/12用戶自訂終止應用層自定義協議

完整列表:man 7 signal 或 kill -l。

Shell 實戰操作

# 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。
  • 訊號處理器中**只能呼叫 Async-Signal-Safe 函數** (man 7 signal-safety)。

實用技巧

  • trap 'cmd' SIG:Shell 腳本捕捉訊號 (清理暫存檔、優雅關閉)。
  • nohup 實作原理:忽略 SIGHUP + 重導向輸出。
  • systemd 服務關閉順序:SIGTERM → 等待 TimeoutStopSec → SIGKILL。

Linux 訊號機制示意圖

copyright © 萬盛學電腦網 all rights reserved