Linux信號(hào)機(jī)制解析
發(fā)表時(shí)間:2023-08-06 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]在Linux中信號(hào)也稱為軟中斷,進(jìn)程在收到信號(hào)之后在對(duì)信號(hào)進(jìn)行處理,可以說就是一個(gè)中斷的過程。本文就來為大家簡(jiǎn)單地解析一下Linux信號(hào)機(jī)制。1、安裝信號(hào)處理函數(shù)在系統(tǒng)編程的層面上與信號(hào)的處理關(guān)系最...
在Linux中信號(hào)也稱為軟中斷,進(jìn)程在收到信號(hào)之后在對(duì)信號(hào)進(jìn)行處理,可以說就是一個(gè)中斷的過程。本文就來為大家簡(jiǎn)單地解析一下Linux信號(hào)機(jī)制。
1、安裝信號(hào)處理函數(shù)
在系統(tǒng)編程的層面上與信號(hào)的處理關(guān)系最直接相關(guān)的函數(shù)有兩個(gè),他們用來安裝信號(hào)處理函數(shù):
sighandler_t signal(int signum, sighandler_t handler);
int sigaction(int signum, const struct sigaction *act,,struct sigaction *oldact);
第一個(gè)函數(shù)signal比較簡(jiǎn)單,sighandler_t 是一個(gè)別名,其原型是 typedef void (*sighandler_t)(int),他是一個(gè)函數(shù)指針,接受一個(gè)類型為int的參數(shù)(信號(hào)的編號(hào)),返回void。例如要對(duì)SIGUSR1信號(hào)進(jìn)行處理:
void handler(int sig)
{
//strsiganl 功能是把信號(hào)的編號(hào)轉(zhuǎn)為信號(hào)說明的字符串
printf(“Rcv a signal:%s”,strsignal(sig));
}
int main()
{
signal(SIGUSR1,handler);
while(1)
;
}
。ㄟ@段程序其實(shí)是有問題的,后面會(huì)說到)這段程序本來是一段死循環(huán),但是對(duì)他發(fā)送SIGUSR1信號(hào),程序會(huì)從while中“中斷”轉(zhuǎn)去執(zhí)行handler中的代碼。在shell中使用kill命令發(fā)送信號(hào)SIGUSR1 于是程序就答應(yīng)出了一段這樣的信息:Rcv a signal:User defined signal 1。signal()的用法幾乎就是這么簡(jiǎn)單。但是由于可移植的原因,參與項(xiàng)目開發(fā)時(shí),應(yīng)該使用下面的這個(gè)函數(shù)。
sigaction()函數(shù)的參數(shù)中有兩個(gè)結(jié)構(gòu)體,其man手冊(cè)原型如下:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
據(jù)我所知sa_handler和sa_sigaction其實(shí)是在一個(gè)union中,他們都是指向信號(hào)處理函數(shù)的指針。
sa_mask 是要屏蔽的信號(hào),sa_flags 有多種選項(xiàng)。(關(guān)于這兩點(diǎn)后文再細(xì)說)。從sigaction()原型中可以發(fā)現(xiàn)參數(shù)中有兩個(gè)struct sigaction參數(shù),其中act是要安裝的信號(hào)處理,而oldact是用來帶回原來的處理方式方便我們處理完信號(hào)后的恢復(fù)。如果不需要拿回之前的信號(hào)處理方式可以把第三個(gè)參數(shù)置為NULL,反之如果只想得到之前的處理方式而不像安裝新的信號(hào)處理,可以把第二個(gè)參數(shù)置為NULL,這點(diǎn)用signal()是辦不到的。用sigaction()改寫上面的例子是這樣的:
1 void handler(int sig)
2 {
3 printf(“Rcv a signal:%s”,strsignal(sig));
4 }
5
6 int main()
7 {
8 struct sigaction act;
9 sigemptyset(&act.sa_mask);
10 act.sa_handler = handler;
11 act.sa_flags = 0;
12 sigaction(SIGUSR1,&act,NULL);
13 while(1)
14 ;
15 }
Linux是一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng)