在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.與程序列外事件相關的訊號。如程序越界,或企圖寫乙個唯讀的記憶...