linux訊號總結

2021-07-09 13:26:52 字數 2804 閱讀 7354

linux中在執行一些程序時有時肯定因為一些內部或外部的原因需要中斷,這就是軟中斷,通過訊號來實現。下面介紹一些中斷,後續會有增加,可能有不足的地方望指正。

一、傳統的訊號處理方式signal()函式,這一函式相對比較簡單:

void (*signal(int signo, void (*func)(int)))(int);

可分解為:

typedef void sigfunc(int);

sigfunc *signal(int signo, sigfunc *));

第乙個引數指定訊號的值,第二個引數指定針對前面訊號值的處理,可以忽略該訊號(引數設為sig_ign);可以採用系統預設方式處理訊號(引數設為sig_dfl);也可以自己實現處理方式(引數指定乙個函式位址)。
由於signal()函式的功能有限,在此就不詳細描述為何有限。unix又引進了sigaction()函式,它包含了signal的所有功能,並且有很多的選擇性。下面就來介紹:

二、sigaction()函式

int sigaction(int signo,const struct sigaction * restrict act,struct sigaction * restrict oldact));

第二和第三個引數都是關於sigaction陣列的,下面主要介紹:

struct sigaction
sa_handler和signal一樣是sig_ign或sig_dfl或是處理訊號的函式,如果是最後乙個,則sa_mask欄位說明了乙個訊號集,在呼叫該訊號捕捉函式之前,這一訊號集要加到程序的訊號遮蔽字中。僅當從訊號捕捉函式返回時再將程序的訊號遮蔽字復位為原先值。這樣,在呼叫訊號處理程式時就能阻塞某些訊號。在訊號處理程式被呼叫時,作業系統建立的新訊號遮蔽字包括正被遞送的訊號。因此保證了在處理乙個給定的訊號時,如果這種訊號再次發生,那麼它會被阻塞到對前乙個訊號的處理結束為止。

sa_flags引數

詳解參見:

sa_sigaction欄位是乙個替代的訊號處理程式,當在sigaction結構中使用了sa_siginfo標誌時,使用該訊號處理程式。對於sa_sigaction欄位和sa_handler欄位這兩者,其實現可能使用同一儲存區,所以應用程式只能一次使用這兩個欄位中的乙個。

通常,按下列方式呼叫訊號處理程式:

void handler(int signo);

但是,如果設定了sa_siginfo標誌,那麼按下列方式呼叫訊號處理程式:

void handler(int signo, siginfo_t *info, void *context);

siginfo_t結構包含了訊號產生原因的有關資訊。該結構的大致樣式如下所示:

struct siginfo ;
各種訊號的si_code值(包括上面的相關資料結構和標誌選項),可通過man sigaction命令進行檢視。

若訊號是sigchld,則將設定si_pid、si_status和si_uid欄位。

若訊號是sigill或sigsegv,則si_addr包含造成故障的根源位址,儘管該位址可能並不準確。

若訊號是sigpoll,那麼si_band欄位將包含streams訊息的優先順序(priority band),該訊息產生poll_in、poll_out或poll_msg事件。

si_errno欄位包含錯誤編號,它對應於引發訊號產生的條件,並由實現定義。

訊號處理程式的context引數是無型別指標,它可被強制轉換為ucntext_t結構型別,用於標識訊號傳遞時程序的上下文。

三、sigprocmask()阻塞訊號函式

在任何時候乙個程序都有一些訊號被阻塞。注意是阻塞而不是忽略。這個訊號就稱為訊號擋板,通過sigprocmask可以修改這個被阻塞的訊號集。

int sigprocmask(int how, const sigset_t *restrict

set, sigset_t *restrict oldset);

how:用於指定訊號修改的方式,可能選擇有三種

sig_block//將set所指向的訊號集中包含的訊號加到當前的訊號掩碼中。即訊號掩碼和set訊號集進行或操作。

sig_unblock//將set所指向的訊號集中包含的訊號從當前的訊號掩碼中刪除。即訊號掩碼和set進行與操作。

sig_setmask //將set的值設定為新的程序訊號掩碼。即set對訊號掩碼進行了賦值操作。

set:為指向訊號集的指標,在此專指新設的訊號集,如果僅想讀取現在的遮蔽值,可將其置為null。

oldset:也是指向訊號集的指標,在此存放原來的訊號集。可用來檢測訊號掩碼中存在什麼訊號。

sigsetops構造訊號集:

sigemptyset()初始化時設定的優先順序設為 empty ,與所有訊號設定.

sigfillset()初始化設定,包括所有訊號.

sigaddset()和sigdelset()訊號 signum 中新增和刪除分別設定.

注意:

......

sigprocmask(sig_block,&sigs,&prevsigs);

//...modify data structure here...

sigprocmask(sig_set,*prevsigs,null);

......

這裡在修改訊號擋板時會儲存先前的設定 prevsigs,然後在對資料進行修改,最後用儲存的設定prevsigs來恢復原來的訊號擋板。除非目的就是修改獲取修改獲取的資源,否則釋放資源時恢復獲取時的狀態是個好習慣。

Linux程序訊號筆記總結

訊號 作用 為了通知我們某個事件的發生 就是乙個軟中斷,通知程序發生某件事情,打斷程序當前的操作,去先處理這個事件 必須認識訊號,訊號不是立即處理的。而實現記錄下來,選擇乙個合適的事機處理 訊號必須有預設的處理方式,當然也可以改變。訊號是可以被阻塞,暫時不處理 訊號的週期性 生命週期 產生 註冊 登...

Linux 程序通訊之 訊號和訊號量總結

如今最經常使用的程序間通訊的方式有 訊號,訊號量,訊息佇列,共享記憶體。所謂程序通訊,就是不同程序之間進行一些 接觸 這種接觸有簡單,也有複雜。機制不同,複雜度也不一樣。通訊是乙個廣義上的意義,不僅僅指傳遞一些massege。他們的用法是基本相同的,所以僅僅要掌握了一種的用法,然後記住其他的用法就能...

linux訊號 阻塞訊號

1.訊號在核心中的表示 我們知道了訊號產生的各種原因,而實際執行訊號處理的動作,叫做訊號遞達 delivery 訊號從產生到遞達之間的狀態,稱為訊號未決 pending 程序可以選擇阻塞 block 某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作。注意,阻...