Linux訊號捕捉及其處理

2021-07-09 08:37:03 字數 2175 閱讀 7339

一、signal訊號處理機制

可以用函式signal註冊乙個訊號捕捉函式,其函式原型為:

#include typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

下面用乙個例子來介紹signal的用法:

在shell中ctrl+c組合鍵會產生乙個sigint訊號,其預設處理動作為終止當前程序,我們用下面的程式捕捉sigint訊號並改變其預設行為,使得捕捉到sigint訊號後讓程式執行列印動作。

#include#include#include#includevoid sig_handler(int sig)

int main()

return 0;

}

可以看到我們已經成功的更改了sigint訊號的預設行為,程序捕捉到訊號後執行我們定義的處理函式。

二、sigaction訊號處理機制

signal函式大部分情況下可以完成訊號處理的要求,但是有些情況下signal函式還是不夠健壯。

例如下面一些特殊情況下,signal函式並不能很好的處理。

註冊乙個訊號處理函式,並且處理完畢乙個訊號之後,是否需要重新註冊,才能夠捕捉下乙個訊號;

如果訊號處理函式正在處理訊號,並且還沒有處理完畢時,又發生了乙個同型別的訊號,這時該怎麼處理;

如果訊號處理函式正在處理訊號,並且還沒有處理完畢時,又發生了乙個不同型別的訊號,這時該怎麼處理;

如果程式阻塞在乙個系統呼叫(如read(…))時,發生了乙個訊號,這時是讓系統呼叫返回錯誤再接著進入訊號處理函式,還是先跳轉到訊號處理函式,等訊號處理完畢後,系統呼叫再返回。

其函式原型為:

#includeint sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
引數signum為需要捕捉的訊號;

引數 act是乙個結構體,裡面包含訊號處理函式位址、處理方式等資訊。

引數oldact是乙個傳出引數,sigaction函式呼叫成功後,oldact裡面包含以前對signum的處理方式的資訊。

如果函式呼叫成功,將返回0,否則返回-1。

該結構體的各欄位含義及使用方式:

欄位sa_handler是乙個函式指標,用於指向原型為void handler(int)的訊號處理函式位址, 即老型別 的訊號處理函式;

欄位sa_sigaction也是乙個函式指標,用於指向原型為

void handler(int isignnum,siginfo_t *psigninfo,void *preserved);
的訊號處理函式,即新型別的訊號處理函式。該函式的三個引數含義為:

欄位sa_handler和sa_sigaction只應該有乙個生效,如果想採用老的訊號處理機制,就應該讓sa_handler指向正確的訊號處 理函式;否則應該讓sa_sigaction指向正確的訊號處理函式,並且讓字段sa_flags包含sa_siginfo選項。

欄位sa_mask是乙個包含訊號集合的結構體,該結構體內的訊號表示在進行訊號處理時,將要被阻塞的訊號。針對sigset_t結構體,有一組專門的函式對它進行處理,它們是:

#includeint sigemptyset(sigset_t *set);  //清空訊號集合set

int sigfillset(sigset_t *set); //將所有訊號填充進set中

int sigaddset(sigset_t *set, int signum); //往set中新增訊號signum

int sigdelset(sigset_t *set, int signum); //從set中移除訊號signum

int sigismember(const sigset_t *set, int signum); //判斷signnum是不是包含在set中

#include#include#include#includevoid sig_handler(int sig)

int main()

return 0;

訊號 訊號處理函式(捕捉)

要明白訊號處理函式的使用,就要先知道訊號的捕捉設定,什麼時候會呼叫訊號處理函式和其執行的流程是什麼,下圖完整的展示了訊號捕捉的設定,以及訊號處理函式的觸發機制 所以,從上圖可以知道,只有當程式中斷,異常或系統呼叫,才會進入核心態,也只有進入了核心態才能處理訊號,在這裡初學者常常有乙個誤區,他們會覺得...

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

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

golang 訊號捕捉和處理

捕捉和處理訊號可以實現優雅start和restart等。golang的signal提供了相關的方法。這裡是乙個模板,目錄結構 sig sig.go test.go 先看如何呼叫 1.new出乙個物件 2.register訊號與對應的處理函式 3.定義os.signal型別的channel,呼叫sig...