理解 Linux 信號機制,關鍵在於區分兩個易混淆的概念:
參考 APUE 範例:進程調用 sigprocmask 阻塞 SIGQUIT → sleep(5) 期間按下 Ctrl+\ 產生信號 → 信號因阻塞變為「未決」 → sleep 返回 → 再次 sigprocmask 解除阻塞 → sigprocmask 返回前,未決信號立即被處理(執行處理函數)。
關鍵結論: 信號被阻塞並未丟棄,解除阻塞瞬間自動處理所有未決同類信號(標準信號僅處理一次,實時信號排隊處理)。
#include <signal.h>
// 獲取未決信號集
int sigpending(sigset_t *set);
// 信號屏蔽字操作
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
// how: SIG_BLOCK(阻塞) | SIG_UNBLOCK(解除) | SIG_SETMASK(設定)
kill()/sigqueue() 觸發。task_struct->pending.signal 集合,攜帶資訊存入 sigqueue 鏈表。
sigqueue、準備調用處理函數。標準信號同步清除集合位,實時信號視鏈表剩餘節點決定。struct sigpending {
struct sigqueue *head, **tail; // 未決信號資訊鏈
sigset_t signal; // 未決信號集
};
struct sigqueue {
struct sigqueue *next;
siginfo_t info; // 信號攜帶資訊
};
「阻塞」是開關,「未決」是狀態。掌握 sigprocmask/sigpending 配合信號集操作,能精準控制信號遞達時機,是編寫健壯並發程式的基石。
Linux 字符設備驅動開發全流程:file_operations、cdev 註冊與用戶空間交互
ARM Linux I/O 記憶體靜態映射 (map_desc / iotable_init) 實作詳解
Linux Shell 文本處理利器 uniq 命令全解析:去重、計數、字段忽略與實戰案例
uBoot 與 Linux 核心關鍵位址參數對照表與啟動流程解析
SUSE Linux 10 硬碟安裝兩大法:GRUB 引導與 Loadlin DOS 啟動完整教學
Python 腳本自動更新 Google Hosts (Windows 適用)