首先來再次看看這張圖:
從上圖來看,每個訊號只有乙個bit的未決標誌,非0即1,不記錄該訊號產生了多少次,阻塞標誌也是這樣表示的。因此,未決和阻塞標誌可以用相同的資料型別sigset_t來儲存,sigset_t稱為訊號集,這個型別可以表示每個訊號的「有效」或「無效」狀態,在阻塞訊號集中「有效」和「無效」的含義是該訊號是否被阻塞,而在未決訊號集中「有效」和「無效」的含義是該訊號是否處於未決狀態。
阻塞訊號集也叫做當前程序的訊號遮蔽字(signal mask),這裡的「遮蔽」應該理解為阻塞而不是忽略。不能對sigset_t進行位操作,去修改裡面的內容,因為我們不知道他的底層裡面都存放的是什麼,它只是幫助我們拿到作業系統底層的資料,因此我們要對位圖進行操作時必須要使用作業系統提供的訊號集操作函式。
sigset_t型別對於每種訊號用乙個bit表示「有效」或「無效」狀態,至於這個型別內部如何儲存這些bit則依賴於系統
實現,從使用者的角度是不必關心的,使用者只能呼叫以下函式來操作sigset_ t變數,而不應該對它的內部資料做
任何解釋,比如用printf直接列印sigset_t變數是沒有意義的。
#include 1.int sigemptyset(sigset_t *set); //初始化訊號集、清空
2.int sigfillset(sigset_t *set); //填滿訊號集
3.int sigaddset (sigset_t *set, int signo); //把某個訊號新增到訊號集
4.int sigdelset(sigset_t *set, int signo); //刪除訊號集中的某個訊號
5.int sigismember(const sigset_t *set, int signo); //判斷乙個訊號是否在訊號集中
這四個函式都是成功返回0,出錯返回-1。sigismember是乙個布林函式,用於判斷乙個訊號集的有效訊號中是否包含呼叫函式sigprocmask可以讀取或更改程序的訊號遮蔽字(阻塞訊號集)。某種 訊號,若包含則返回1,不包含則返回0,出錯返回-1。
#include int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
返回值:若成功則為0,若出錯則為-1
如果oset是非空指標,則讀取程序的當前訊號遮蔽字通過oset引數傳出。如果set是非空指標,則更改程序的訊號遮蔽字,引數how指示如何更改。如果oset和set都是非空指標,則先將原來的訊號遮蔽字備份到oset裡,然後根據set和how引數更改訊號遮蔽字。假設當前的訊號遮蔽字為mask,下表說明了how引數的可選值。
sig_blockset包含了我們希望新增到當前訊號遮蔽字的訊號,相當於mask=mask|set
sig_unblockset包含了我們希望從當前訊號遮蔽字中解除阻塞的訊號,相當於mask=mask&~set
sig_setmask設定當前訊號遮蔽字為set所指向的值,相當於mask=set
如果呼叫sigprocmask解除了對當前若干個未決訊號的阻塞,則在sigprocmask返回前,至少將其中乙個訊號遞達。
讀取當前程序的未決訊號集,通過set引數傳出。
Linux 訊號的理解以及訊號集處理函式的使用
通過終端按鍵產生。如ctrl c 終止程序 通過系統函式向程序傳送訊號。如kill 函式,給指定程序傳送訊號。有軟體條件產生訊號。如alarm 函式,設定乙個鬧鐘訊號。硬體異常。如記憶體越界,除0異常。傳送訊號給程序 include include int kill pid t pid,int si...
Linux下的訊號以及訊號的處理
阻塞訊號 訊號捕捉 訊號處理 根據生活中的經驗,訊號就是向乙個事物傳遞某些資訊,在shell下啟動乙個前台程序,使用者輸入ctrl c,這個過程就相當於是再給核心傳遞乙個程序取消的訊號。那麼使用者按下ctrl c後,發生了什麼?在鍵盤上按下ctrl c等來產生訊號 include intkill p...
linux 訊號處理 三 (訊號集的使用)
sigprocmask系統呼叫 使用條件 1 有時候不希望在接到訊號時就立即停止當前執行,去處理訊號,同時也不希望忽略該訊號,而是延時一段時間去呼叫訊號處理函式。這種情況是通過阻塞訊號實現的。2 訊號阻塞和忽略訊號的區別。阻塞的概念和忽略訊號是不同的。作業系統在訊號被程序解除阻塞之前不會講訊號傳遞出...