Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 信號機制深度解析:信號掩碼、阻塞與 sigaction 實戰

編輯:Linux 教學

信號是 Linux 進程間通訊最基礎也最關鍵的機制之一。本文系統梳理信號集操作、阻塞與忽略的本質區別、sigprocmask 動態修改信號掩碼、sigaction 註冊處理函數的完整語義,為開發高可靠系統軟體奠定理論基礎。

核心概念:信號掩碼與被阻塞信號集

每個進程擁有獨立的 sigset_t 類型信號掩碼,標記哪些信號被阻塞。信號被阻塞時,內核暫緩投遞,不影響進程當前行為;解除阻塞後信號才會被遞送。子進程 fork() 時會繼承父進程的信號掩碼。

阻塞 vs 忽略:本質區別

維度阻塞忽略
信號投遞暫緩,解除阻塞後投遞立即投遞,但進程丟棄不處理
進程行為不受影響不處理,相當於無視
典型場景臨界區保護、原子操作不關心的信號(如 SIGCHLD 防殭屍)

信號集操作 API 全景

int sigemptyset(sigset_t *set);      // 清空集合
int sigfillset(sigset_t *set);       // 填入所有信號
int sigaddset(sigset_t *set, int signum);   // 加入指定信號
int sigdelset(sigset_t *set, int signum);   // 移除指定信號
int sigismember(const sigset_t *set, int signum); // 判斷是否包含

常用模式:sigemptyset() 初始化 → sigaddset() 逐個加入;或 sigfillset() 全加入 → sigdelset() 排除特定信號。

sigprocmask:動態修改進程信號掩碼

#include <signal.h>
int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old);

how 三種模式:

  • SIG_BLOCK:將 set 加入當前阻塞集(聯集)
  • SIG_UNBLOCK:從當前阻塞集移除 set(差集)
  • SIG_SETMASK:直接以 set 替換當前阻塞集

set 為 NULL 時不修改,僅查詢;old 為 NULL 時不返回舊掩碼。

sigaction:工業級信號處理註冊

struct sigaction {
    void (*sa_handler)(int);                 // 舊版處理函數
    void (*sa_sigaction)(int, siginfo_t*, void*); // 新版處理函數
    sigset_t sa_mask;                        // 處理期間額外阻塞的信號集
    int sa_flags;                            // 行為標誌位組合
    void (*sa_restorer)(void);               // 保留字段
};

關鍵字段詳解

  • sa_handler / sa_sigaction:二擇一。使用新版需設置 SA_SIGINFO 標誌,新版可獲取 siginfo_t 詳細信號上下文
  • sa_mask:處理函數執行期間自動阻塞的信號集,防止重入或競態
  • sa_flags 核心標誌位:
    • SA_RESETHAND:處理一次後自動重置為預設動作
    • SA_NODEFER:允許遞歸處理同一信號(忽略 sa_mask)
    • SA_RESTART:系統調用被中斷後自動重啟(強烈建議啟用)
    • SA_SIGINFO:啟用新版處理函數

sigprocmask vs sa_mask:作用域區別

sigprocmask 是「全程阻塞」,修改後持續生效直到再次修改;sa_mask 僅在「處理特定信號的當下」生效,屬於臨時性阻塞。兩者配合使用可構建精細的信號同步策略。


實戰建議:多線程程序中信號處理極其複雜,建議採用「專用信號處理線程 + sigwaitinfo()」模型,避免在主業務邏輯中直接處理異步信號。

Copyright © Windows教程網 All Rights Reserved