Linux下的訊號以及訊號的處理

2021-09-03 07:10:37 字數 3111 閱讀 8467

阻塞訊號

訊號捕捉

訊號處理

根據生活中的經驗,訊號就是向乙個事物傳遞某些資訊,在shell下啟動乙個前台程序,使用者輸入ctrl+c,這個過程就相當於是再給核心傳遞乙個程序取消的訊號。

那麼使用者按下ctrl+c後,發生了什麼?

在鍵盤上按下ctrl+c等來產生訊號
#include

intkill

(pid_t pid,

int signo)

;// 成功返回0,錯誤返回-1

#include

unsigned

intalarm

(unsigned

int seconds)

;//呼叫alarm函式可以設定乙個鬧鐘,告訴核心在second秒之後給當前程序傳送sigalrm訊號,該訊號預設處理方式為終止當前程序

//second為0表示取消之前設定的鬧鐘

在當前程序執行了除以0的指令,cpu的運算單元會產生異常,核心將這個異常解釋為sigfpe訊號傳送給程序,或者當前程序訪問了非法記憶體位址,mmu產生異常,核心將這個異常解釋為sigsegv訊號傳送給程式
實際執行訊號處理的動作稱作訊號遞達訊號從產生到遞達之間的狀態稱為訊號未決程序可以選擇阻塞某乙個訊號,被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞才執行遞達動作

如上如所示,sighup訊號未產生,sigint訊號已經產生但是正在被阻塞,所以暫時不能遞達,sigquit訊號從未產生,但是一旦產生它將會被阻塞。

程序在解除某乙個訊號的阻塞之前,這個訊號產生過多次,如果是不可靠訊號,產生多次會當做一次處理,而對於可靠訊號來說,產生的訊號會依次放在乙個佇列裡,將來一一處理。

每個訊號都有乙個未決狀態的標誌,不記錄該訊號產生了多少次,可以用sigset_t來儲存,sigset_t就稱作為訊號集,這個型別可以表示訊號的有效或無效狀態。

#include

intsigemptyset

(sigset_t *set)

;//初始化set所指向的訊號集,使其中所有位元位清0

intsigfillset

(sigset_t *set)

;//初始化set所指向的訊號集,使其中所有訊號的對應bit置位

intsigaddset

(sigset_t *set,

int signum)

;int

sigdelset

(sigset_t *set,

int signum)

;int

sigismember

(const sigset_t *set,

int signum)

;//判斷訊號是否在集合中

讀取或者更改程序訊號遮蔽字sigprocmask

int

sigprocmask

(int how,

const sigset_t *set, sigset_t *oldset)

;

oldset為空,則讀取程序當前訊號的訊號遮蔽字,通過oldset傳出

oldset非空,更改程序的訊號遮蔽字,how顯示如何更改

oldset和set都不為空,則將原來的訊號遮蔽字備份到oldset裡,然後修改訊號遮蔽字

how

explain

sig_block

set包含了新增到當前訊號遮蔽字的訊號

sig_unblock

set包含了從當前訊號中解除阻塞的訊號

sig_setmask

設定當前的訊號遮蔽字為set所指向的值

讀取當前程序的未決訊號集sigpending

;使用sigaction重新定義sigint的訊號處理動作

Linux下的訊號(二) 阻塞訊號

1,在此之前,必須先了解幾個概念 訊號遞達 delivery 實際執行訊號處理的動作。訊號未決 pending 訊號從產生到遞達之間的狀態。訊號阻塞 block 被阻塞的訊號產生時將保持在未決狀態,直到 程序解除對此訊號的阻塞,才 執行遞達的動作。注意 訊號阻塞和訊號忽略是不同的。只要訊號被阻塞就不...

Linux下的訊號

訊號是作業系統發給程序的一種資訊,程序會針對接收到的資訊做出相應的處理。前面談到乙個概念,叫做訊號量,這裡所說的訊號量和我們今天談到的訊號,除了名字相似,事實上並沒有任何聯絡,是兩個完全不相關的概念,故不可混為一談。訊號是如何產生的呢?先來說說熟悉的場景 使用者輸入命令,在前台啟動乙個程序,然後按下...

Linux 訊號的捕捉過程以及訊號捕捉函式

我們都說訊號的產生之後不是被立即處理的,而是在合適的時候,那麼合適的時候是什麼時候呢?訊號又是怎麼 捉的呢?合適的時候是指 從核心態切換為使用者態時進行訊號的捕捉 在linux下,我們會發現我們有時候會有一些檔案不能進入,有一些檔案不能建立,其實這就是一種許可權。核心態和使用者態都是一種狀態,這兩種...