linux訊號學習

2021-06-22 12:29:14 字數 3783 閱讀 7552

在linux中,訊號是程序間通訊的一種方式,它採用的是非同步機制。當訊號傳送到某個程序中時,作業系統會中斷該程序的正常流程,並進入相應的訊號處理函式執行操作,完成後再回到中斷的地方繼續執行。

訊號處理函式的註冊,linux系統訊號機制最簡單的介面是signal函式

#include void (*signal(int sig, void (*func)(int)))(int);
signal函式接收兩個引數,第乙個引數指定其要響應的訊號,是乙個整數,第二個引數指定新的訊號響應函式。

signal的返回值是乙個函式指標,指向的是該訊號老的處理函式。

這樣的定義不是很直觀,可以採用typedef的方式,使定義看起來更簡單一點。

typedef void sigfun(int);

sigfun* signal(int,sigfun*);

通過乙個例子說明一下signal的用法:

#include#include#includevoid sig_handler(int sig)

int main()

return 0;

}

執行結果:

執行結果:

sigint為終端終止符,按下ctrl-c可以產生中斷訊號(sigint),使程式終止執行,但是這裡通過signal函式重新設定了sigint的響應函式,所以第一按下ctrl-c時,列印signal catched 字元,同時將sigint的響應函式設定回系統預設的處理函式,這樣在第二次按ctrl-c時,程式結束執行。

訊號傳送函式kill()和raise()

kill函式將訊號傳送給程序和程序組,raise函式則允許程序向自己傳送訊號。

函式原型為:

#includeint kill(pid_t pid,int signo);

int raise(int signo);

alarm和pause函式

使用alarm函式可以設定乙個計時器,計時器在超時時會產生sigalrm訊號

#includeunsigned int alarm(unsigned int seconds);
號引數seconds單位為秒,經過seconds秒後計時器超時,函式返回值為上一次設定的鬧鐘時間的剩餘留秒數。

pause函式使程序掛起直至捕捉到乙個訊號

#includeint pause(void);
乙個使用alarm和pause函式的例子:

#include#include#includeint flag=0;

static void sig_handler(int sig)

int main()

if(pid==0)

signal(sigalrm,sig_handler);

while(!flag)

if(flag)

printf("alarm catched\n");

exit(0);

}

執行結果:

子程序在等待3秒後向父程序傳送sig_alrm訊號,父程序在sig_alrm訊號處理函式中修改flag的值,父程序主程式判斷flag值,退出while迴圈。

訊號集訊號集(signal set)是一種能夠表示多個訊號的資料型別,訊號集其實是點陣圖,用一位來表示乙個訊號。

訊號集的資料型別為sigset_t,對應的,有五個處理訊號集的函式

#includeint sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set,int signo);

int sigismember(const sigset_t *set,int sigo);

這五個函式分別完成以下功能:

清除訊號集中的所有訊號

將sigset_t中的每一位都設為1

增加乙個特定訊號到訊號集中

刪除訊號集中的乙個特定訊號

判斷乙個訊號是否位於訊號集中

sigprocmask函式

sigprocmask()可以用來檢測或改變目前的訊號遮蔽字,其操作依引數how來決定,如果引數oldset不是null指標,那麼目前的訊號遮蔽字會由此指標返回。如果set是乙個非空指標,則引數how指示如何修改當前訊號遮蔽字

函式原型為:

#includeint sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oldset);
其中引數how表示對訊號集的處理方式:

sig_block新的訊號遮蔽字是當前訊號遮蔽字和set指定遮蔽字的並集

sig_unblock新的訊號遮蔽字是

當前訊號遮蔽字和set指定遮蔽字的交集

sig_setmask該程序新的訊號遮蔽是set指向的值

阻塞乙個訊號的例子:

void main()

sigaction函式

sigaction函式的功能是檢查或修改指定訊號的處理函式

函式原型:

#include int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
signo表示要處理的訊號

act和oact分別表示要設定的和之前的處理動作

sigaction 型別用來描述對訊號的處理,定義如下:

struct sigaction

;

成員 sa_handler 是乙個函式指標,其含義與 signal 函式中的訊號處理函式類似。

sa_mask是乙個訊號集,在呼叫該訊號處理函式之前,這一訊號集要加到程序的訊號遮蔽字中。

sa_sigaction 則是乙個替代的訊號處理程式,

當 sa_flags 成員的值

包含了 sa_siginfo 標誌時,系統將使用 sa_sigaction 函式作為訊號處理函式。

signal函式就是用sigaction實現的。

乙個例子:

#include #include #include #include static void sig_usr(int signum)

else if(signum == sigusr2)

else

}int main(void)

}else

}return 0;

}

執行結果:

Linux學習系列 訊號

訊號是軟體中斷,提供了典型的非同步機制。每個訊號有乙個編號,訊號分為兩類 非實時訊號和實時訊號。0 31編號屬於非實時訊號 31 63編號屬於實時訊號。為什麼會分為這兩類訊號呢?這個主要是因為歷史原因,首先實現的是非實時訊號,非實時訊號也成為不可靠訊號,是因為其實現機制導致這類訊號可能會丟失 而實時...

linux學習 訊號簡介

訊號 簡單理解為軟體中斷 訊號產生 1 按鍵產生訊號,例如ctrl c 2 硬體異常產生訊號,例如無效的記憶體引用 3 程序呼叫kill函式將訊號傳送給其他程序 4 使用者用kill命令將訊號傳送給程序 5 某種軟體條件發生,比如alarm函式設定的定時器已超時 訊號的處理 1 忽略此訊號,大多數訊...

linux學習筆記之訊號

訊號機制是程序之間想回傳遞訊息的一種方法,應用於非同步事件的處理,訊號全稱為軟中斷訊號,它被傳送給乙個正在被執行的程序以通知該程序有某一件事發生。發出訊號的原因有很多 1.與程序終止有關的訊號。當程序退出或子程序終止時,會發出這類訊號 2.與程序列外事件相關的訊號。如程序越界,或企圖寫乙個唯讀的記憶...