linux 訊號相關概念

2021-07-03 17:25:08 字數 2204 閱讀 1038

訊號的阻塞就是讓系統暫時保留訊號待以後傳送。由於另外有辦法讓系統忽略訊號,所以一般情況下訊號的阻塞只是暫時的,只是為了防止訊號打斷敏感的操作。

當需要修改某些全域性變數時,可以通過sigprocmask()函式阻塞處理函式中也使用該變數的訊號。

在某些訊號處理函式中,為了防止同類訊號的到來,可以使用sigaction()函式的sa_mask阻塞特定的訊號。

阻塞訊號的作用

使用函式sigprocmask()阻塞訊號的傳遞,只是延遲訊號的到達。訊號會在解除阻塞後繼續傳遞。這種情況往往需要在訊號程式和其它程式共享全域性變數時,如果全域性變數的型別不是sig_atomic_t型別,當一部分程式恰好讀、寫到變數過程中,產生某個訊號,而訊號程式裡會改變該變數,那麼就會產生混亂。為了避免這種混亂,提供程式的可靠性,你必須在操作這類變數前阻塞訊號,操作完成後恢復訊號的傳遞。

訊號集所有的訊號阻塞函式都使用稱作訊號集的資料結構來表明受到影響的訊號。每乙個操作都包括兩個階段:建立訊號集,傳遞訊號集給特定的庫函式。下面說明訊號集和相關的資料型別:

sigset_t:這個資料型別用來代表訊號的集合,有兩種方法對它進行初始化。一種是通過函式sigemptyset()使之不包含任何訊號,然後用sigaddset()函式加入需要的訊號。另一種方法是通過函式sigfillset()使之包含所以訊號,然後通過sigdelset()函式刪除我們不需要的訊號。注意,千萬不用試圖通過手工方式直接操作這種型別變數,否則會帶來嚴重的錯誤。下面介紹相關的函式。

int sigemptyset(sigset_t *set):初始化訊號集set使之不包含任何訊號,這個函式總是返回0。

int sigfillset(sigset_t *set):初始化訊號集set使之包含所有的訊號,這個函式也是總返回0。

int sigaddset(sigset_t *set, int signum):該函式把訊號signum加入到訊號集set中,需要注意的是這個函式只是修改了set變數本身,並不作其它操作。該函式成功操作返回0,失敗返回-1,錯誤**設定成einval,表示signum不是有效的訊號**。

int sigdelset(sigset_t *set, int signum):該函式從訊號集set中刪除訊號signum,其它方面和sigaddset()函式類似,不再贅述。

int sigismember(const sigset_t *set,int signum):這個函式測試訊號signum是否包含在訊號集合set中,如果包含返回1,不包含返回0,出錯返回-1。錯誤**也只有乙個einval,表示signum不是有效的訊號**。

程序的訊號掩碼

我們稱正在阻塞的訊號的集合為訊號掩碼(signal mask)。每個程序都有自己的訊號掩碼,建立子程序時子程序將繼承父程序的訊號掩碼。我們可以通過修改當前的訊號掩碼來改變訊號的阻塞情況。

int sigprocmask(int how, const sigset_t *set,sigset_t *oldset),該函式用來檢查和改變呼叫程序的訊號掩碼,其中的how引數指出訊號掩碼改變的方式,必須是下面的值之一:

sig_block,阻塞set中包含的訊號。意思是說把set中的訊號加到當前的訊號掩碼中去,新的訊號掩碼是set和舊訊號掩碼的並集。

sig_unblock,解除set中訊號的阻塞,從當前訊號掩碼中去除set中的訊號。

sig_setmask,設定訊號掩碼,既按照set中的訊號重新設定訊號掩碼。

最後乙個引數是程序原來的訊號集。如果你只需要改變訊號的阻塞情況而不需要關心原來的值,可以傳遞null指標給函式。如果你希望什麼也不改變,只是想獲得當前訊號掩碼的資訊,那麼把set設定成null,old中返回當前的設定。

sigprocmask()函式成功返回0,失敗返回-1。失敗時錯誤**只可能是einval,表示引數how不合法。

不能阻塞sigkill和sigstop等訊號,但是當set引數包含這些訊號時sigprocmask()不返回錯誤,只是忽略它們。另外,阻塞sigfpe這樣的訊號可能導致不可挽回的結果,因為這些訊號是由程式錯誤產生的,忽略它們只能導致程式無法執行而被終止。

舉例:禁止關鍵**時訊號到達

假定你建立訊號sigalrm的處理函式,在其中設定乙個標誌。主程式中檢查標誌並清除,使用函式sigprocmask()控制訊號到達:

#include 

volatile sig_atomic_t flag=0;

intmain(void)

sigprocmask(sig_unblock,&block_alarm,null);

... ...}}

訊號相關概念

我記得我在程序間通訊的時候說到過一種方式 訊號量 終止在linux命令列上正在執行的可執行程式所用的ctrl c,也屬於一種訊號 是常見sigint訊號 所以,今天我想具體分享一下與訊號相關的一些概念。linux中訊號共有64個,常見訊號量只有31個,利用kill l命令就可以用來檢視全部訊號,如下...

linux訊號捕獲相關

linux中一共有32種訊號,在 usr include bits signum.h 標頭檔案中可以看到 define sighup 1 define sigint 2 define sigquit 3 define sigill 4 define sigtrap 5 define sigabrt ...

linux 訊號相關函式 一

訊號共性 簡單 不能攜帶大量資訊 滿足條件才傳送 訊號的特質 訊號是軟體層面的 中斷。一旦訊號產生,無論程式執行到什麼位置,必須停止執行,處理訊號,處理結束,再繼續執行後續指令。所有訊號的產生及處理都是 由 核心完成的。產生訊號 1.按鍵產生 如 ctrl c 2.系統呼叫產生 如 kill 3.軟...