訊號捕捉
訊號捕捉特性
核心實現訊號捕捉過程
核心通過讀取未決訊號集來判斷訊號是否應被處理,訊號遮蔽字 mask 可以影響未決訊號集。而我們可以在應用程式中自定義 set 來改變 mask。以達到遮蔽指定訊號的目的。
sigset_t set;
//typedef unsigned long sigset_t;
intsigemptyset
(sigset_t *set)
;//將某個訊號集清零 成功:0;失敗:-1
intsigfillset
(sigset_t *set)
;//將某個訊號集置1 成功:0;失敗:-1
intsigaddset
(sigset_t *set,
int signum)
;//將某個訊號加入訊號集 成功:0;失敗:-1
intsigdelset
(sigset_t *set,
int signum)
;//將某個訊號從訊號集中刪除 成功:0;失敗:-1
intsigismember
(const sigset_t *set,
int signum)
;//判斷某個訊號是否在訊號集中 在集合:1;不在:0
sigset_t 型別的本質是點陣圖。但不應該直接使用位操作,而應該使用上述函式,保證跨系統操作有效。
用來遮蔽訊號、解除遮蔽也使用該函式。其本質,讀取或修改程序的訊號遮蔽字(pcb 中)【注意】遮蔽訊號:只是將訊號處理延後執行(延至解除遮蔽);而忽略表示將訊號丟棄
int
sigprocmask
(int how,
const sigset_t *set, sigset_t *oldset)
;【引數】
1. set:傳入引數,是乙個位圖,set中哪個位置1,就表示遮蔽哪個訊號
2. oldset:傳出引數,儲存舊的訊號遮蔽集
3. how:假設當前的訊號遮蔽字為 mask
- sig_block:當 how 設定為此值,set 表示需要遮蔽的訊號,相當於 mask = mask | set
- sig_unblock:當 how 設定為此值,set 表示需要遮蔽的訊號,相當於 mask = mask &
~set
- sig_setmask:當 how 設定為此值,set 表示用於替代原始遮蔽集的新遮蔽集,相當於 mask = set。
若呼叫 sigprocmask 解除了對當前若干訊號的阻塞,則在 sigprocmask 返回之前,至少將其中乙個訊號遞達。
讀取當前程序的未決訊號集,不能讀取阻塞訊號集,但是可以根據未決訊號集推出阻塞訊號集的狀態
int
sigpending
(sigset_t *set)
;【引數】
set:傳出引數
【返回值】
成功:0;失敗:-
1,設定errno
【練習】列印未決訊號集
#include
#include
#include
void
print
(sigset_t *ped)
else
}printf
("\n");
}int
main()
return0;
}
【執行結果】
註冊乙個訊號捕捉函式:
typedef
void
(*sighandler_t)
(int);
sighandler_t signal
(int signum, sighandler_t handler)
;
該函式由ansi定義,由於歷史原因在不同版本的 unix 中可能有不同的行為。因此應該盡量避免使用它,取而代之的是 sigaction 函式
【舉個栗子】
#include
#include
#include
typedef
void
(*sighandler_t)
(int);
void
fun(
)int
main()
while(1
);return0;
}
【執行結果】每按下 ctrl + \,都會列印 catch
修改訊號處理動作(通常在 linux 用來註冊乙個訊號的捕捉函式)
int
sigaction
(int signum,
const
struct sigaction *act,
struct sigaction *oldact)
;【返回值】
成功:0;失敗:-
1,設定 errno
struct sigaction
;【引數】
1.void
(*sa_handler)
(int);
//捕捉函式
2. sa_mask:用於指定在訊號捕捉函式執行期間所遮蔽的訊號集
3. sa_flags:
[引數說明]【舉個栗子】寫乙個捕捉 sigquit 的訊號處理函式,在訊號處理函式期間,遮蔽 sigtstp 訊號。
#include
#include
#include
typedef
void
(*sighandler_t)
(int);
void
fun()}
intmain()
【執行結果】當 按下 ctrl + \,執行 sigquit 的訊號處理函式(迴圈列印catch),在 sigquit 訊號處理函式期間,若按下 ctrl + z,sigquit 的訊號處理函式不會退出,會繼續執行,但是如果按下 ctrl + c,那麼會去執行 ctrl + c的訊號處理函式,預設退出程序。
程序正常執行時,預設 pcb 中有乙個訊號遮蔽字,它決定了程序自動遮蔽哪些訊號。當註冊了某個訊號捕捉函式,捕捉到該訊號以後,要呼叫該函式。而該函式有可能執行很長時間,在這期間所遮蔽的訊號不由預設訊號遮蔽字來決定,而是由 sa_mask 來指定。呼叫完訊號處理函式,在恢復成預設的。***訊號捕捉函式執行期間,*** 訊號自動被遮蔽
阻塞的常規訊號不支援排隊,產生多次只記錄一次。(後32個實時訊號支援排隊)
Linux通訊之訊號
a給b傳送訊號,b收到訊號之前執行自己的 收到訊號之後,不管執行到程式的什麼位置,都要暫停執行,去處理訊號,處理完畢再繼續執行。與硬體中斷類似 非同步模式。但訊號是軟體層面上實現的中斷,早期常被稱為 軟中斷 訊號的特質 由於訊號是通過軟體方法實現,其實現手段導致訊號有很強的延時性。但對於使用者來說,...
linux之通訊之訊號學習1
比如我們按下了鍵盤或者其它硬體故障 軟體 最常用傳送訊號的系統函式是kill,raise,alarm 和setitimer 以及sigqueue 函式,軟體 還包括一些非法運算等操作。程序可以通過三種方式來響應乙個訊號 1 忽略訊號,即對訊號不做任何處理,其中,有兩個訊號不能忽略 sigkill 及...
linux程序間通訊之訊號
1 wait 函式 原型 pid t wait int status 子程序退出時,它向父程序傳送乙個sigchld訊號,預設情況是總是忽略sigchld訊號,此時程序狀態一直保留在記憶體中,因此需要父程序去處理改訊號,處理的辦法則是呼叫wait 函式,收集子程序狀態資訊,並清空該資訊 使用wait...