1. 訊號在核心中的表示
我們知道了訊號產生的各種原因,而實際執行訊號處理的動作,叫做訊號遞達(delivery)。訊號從產生到遞達之間的狀態,稱為訊號未決(pending)。程序可以選擇阻塞(block)某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作。
注意,阻塞和忽略是不同的,只要訊號被阻塞就不會遞達,而忽略是在遞達之後可選的一種處理動作。
linux --- 訊號 --- 阻塞訊號:
每個訊號都有兩個標誌位分別表示阻塞和未決,,還有乙個函式指標表示處理動作,訊號產生時,核心在程序控制塊中設定該訊號的未決標誌,直到訊號遞達才清除該標誌。
(1) sighup(簡記為00):未阻塞未產生,處理動作遞達執行預設。
(2) sigint(簡記為11):訊號產生被阻塞,暫時不能遞達。處理動作是忽略,但在沒有解除阻塞之前不能忽略這個訊號,因為程序仍有機會改變處理動作之後再解除阻塞。
(3)sigquit(10):未產生,一旦產生sigquit訊號將被阻塞,處理動作是使用者自定義函式sighandler。
如果在程序解除對某訊號的阻塞之前這種訊號產生過多次,將如何處理?
posix.1允許系統遞送該訊號一次或多次。linux是這樣實現的:普通訊號在遞達之前產生多次只計一次,而實時訊號在遞達之前產生多次可以依次放在乙個佇列裡。
從上圖來看,每個訊號只有乙個bit的未決標誌,非0即1,不記錄該訊號產生了多少次,阻塞標誌也是這樣表示的。因此,未決和阻塞標誌可以用相同的資料型別sigset_t來儲存,sigset_t稱為訊號集,這個型別可以表示每個訊號的「有效」或「無效」狀態,在阻塞訊號集中「有效」和「無效」的含義是該訊號是否被阻塞,而在未決訊號集中「有效」和「無效」的含義是該訊號是否處於未決狀態。
即,只表示是否阻塞,不表示次數!
2. 訊號集操作函式
sigset_t型別對於每種訊號用乙個bit表示「有效」或「無效」狀態,至於這個型別內部如何儲存這些bit則依賴於系統實現,從使用者的角度是不必關心的,使用者只能呼叫以下函式來操作sigset_t變數,而不應該對它的內部資料做任何解釋,比如用printf直接列印sigset_t變數是沒有意義的。
#include
int sigemptyset(sigset_t *set); ----- 初始化set指向的訊號集,使其中所有訊號的對應bit清零,表示該訊號集不包含任何有效訊號.
int sigfillset(sigset_t *set); ---- 初始化set所指向的訊號集,使其中所有訊號的對應bit置位,表示該訊號集的有效訊號包括系統支援的所有訊號。
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);判斷乙個訊號集的有效訊號中是否包含某種訊號,若包含則返回1,不含返回0,出錯返回-1,是乙個布林函式;
注意,在使用sigset_t型別的變數之前,一定要呼叫sigemptyset或sigfillset做初始化,使訊號集處於確定的狀態。
前四個函式都是成功返回0,出錯返回-1。
3. sigprocmask
呼叫函式sigprocmask可以讀取或更改程序的訊號遮蔽字(阻塞訊號集)。
#include
int sigprocmask(int how,const siset_t *set,sigset_t *oset);
返回值:成功為 0,出錯為-1;
如果oset是非空指標,則讀取程序的當前訊號遮蔽字通過oset引數傳出。如果set是非空指標,則更改程序的訊號遮蔽字,引數how指示如何更改。如果oset和set都是非空指標,則先將原來的訊號遮蔽字備份到oset裡,然後根據set和how引數更改訊號遮蔽字。假設當前的訊號遮蔽字為mask,下表說明了how引數的可選值。
linux --- 訊號 --- 阻塞訊號:
sigpending 讀取當 前程序的未決訊號集,通過set引數傳出,呼叫成功返回0,出錯返回-1;
5、**如下:
1 #include 2 #include 3 #include 4
5 void printsigset(sigset_t *set)
11 else
14 }
15 puts("");
16 }
17 int main()
18 29 return 0;
30 }
結果如下:
Linux 阻塞訊號
linux中訊號產生的原因大致有一下三種 鍵盤中斷 命令發出 異常產生中斷 但歸根結底,這些訊號其實都是最終有作業系統發出的。常見的對訊號的處理,無外乎以下三種 忽略終止該程序 自定義行為 對訊號的處理動作叫做訊號遞達,在訊號由產生到遞達的過程中還有一種狀態叫做未決。即訊號雖產生,但是未被處理。這個...
Linux入門 訊號(二) 阻塞訊號
實際執行訊號的處理動作稱為訊號遞達 delivery 訊號從產生到遞達之間的狀態,稱為訊號未決 pending 程序可以選擇阻塞 block 某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序接觸對此訊號的阻塞,才執行遞達的操作。阻塞和忽略不同,只有訊號阻塞就不會遞達,而忽略是在訊號遞達之後可選...
Linux下的訊號(二) 阻塞訊號
1,在此之前,必須先了解幾個概念 訊號遞達 delivery 實際執行訊號處理的動作。訊號未決 pending 訊號從產生到遞達之間的狀態。訊號阻塞 block 被阻塞的訊號產生時將保持在未決狀態,直到 程序解除對此訊號的阻塞,才 執行遞達的動作。注意 訊號阻塞和訊號忽略是不同的。只要訊號被阻塞就不...