Linux通訊之訊號(二)

2021-10-08 20:54:15 字數 3786 閱讀 5053

訊號捕捉

訊號捕捉特性

核心實現訊號捕捉過程

核心通過讀取未決訊號集來判斷訊號是否應被處理,訊號遮蔽字 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...