如果進(jìn)程要處理某一信號,那么就要在進(jìn)程中安裝該信號。安裝信號主要用來確定信號值及進(jìn)程針對該信號值的動(dòng)作之間的映射關(guān)系,即進(jìn)程將要處理哪個(gè)信號;該信號被傳遞給進(jìn)程時(shí),將執(zhí)行何種操作。
linux主要有兩個(gè)函數(shù)實(shí)現(xiàn)信號的安裝:signal()、sigaction()。其中signal()在可靠信號系統(tǒng)調(diào)用的基礎(chǔ)上實(shí)現(xiàn),是庫函數(shù)。它只有兩個(gè)參數(shù),不支持信號傳遞信息,主要是用于前32種非實(shí)時(shí)信號的安裝;而sigaction()是較新的函數(shù)(由兩個(gè)系統(tǒng)調(diào)用實(shí)現(xiàn):sys_signal以及sys_rt_sigaction),有三個(gè)參數(shù),支持信號傳遞信息,主要用來與 sigqueue()系統(tǒng)調(diào)用配合使用,當(dāng)然,sigaction()同樣支持非實(shí)時(shí)信號的安裝。sigaction()優(yōu)于signal()主要體現(xiàn)在支持信號帶有參數(shù)。
1、signal()
#include
void (*signal(int signum, void (*handler))(int)))(int);
如果該函數(shù)原型不容易理解的話,可以參考下面的分解方式來理解:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler));
第一個(gè)參數(shù)指定信號的值,第二個(gè)參數(shù)指定針對前面信號值的處理,可以忽略該信號(參數(shù)設(shè)為SIG_IGN);可以采用系統(tǒng)默認(rèn)方式處理信號(參數(shù)設(shè)為SIG_DFL);也可以自己實(shí)現(xiàn)處理方式(參數(shù)指定一個(gè)函數(shù)地址)。
如果signal()調(diào)用成功,返回最后一次為安裝信號signum而調(diào)用signal()時(shí)的handler值;失敗則返回SIG_ERR。
2、sigaction()
#include
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
sigaction函數(shù)用于改變進(jìn)程接收到特定信號后的行為。該函數(shù)的第一個(gè)參數(shù)為信號的值,可以為除SIGKILL及SIGSTOP外的任何一個(gè)特定有效的信號(為這兩個(gè)信號定義自己的處理函數(shù),將導(dǎo)致信號安裝錯(cuò)誤)。第二個(gè)參數(shù)是指向結(jié)構(gòu)sigaction的一個(gè)實(shí)例的指針,在結(jié)構(gòu)sigaction的實(shí)例中,指定了對特定信號的處理,可以為空,進(jìn)程會以缺省方式對信號處理;第三個(gè)參數(shù)oldact指向的對象用來保存原來對相應(yīng)信號的處理,可指定oldact為NULL。如果把第二、第三個(gè)參數(shù)都設(shè)為NULL,那么該函數(shù)可用于檢查信號的有效性。
第二個(gè)參數(shù)最為重要,其中包含了對指定信號的處理、信號所傳遞的信息、信號處理函數(shù)執(zhí)行過程中應(yīng)屏蔽掉哪些函數(shù)等等。
參數(shù)結(jié)構(gòu)sigaction定義如下
struct sigaction
{
void (*sa_handler) (int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer) (void);
}
sa_handler此參數(shù)和signal()的參數(shù)handler相同,代表新的信號處理函數(shù),其他意義請參考signal()。
sa_mask 用來設(shè)置在處理該信號時(shí)暫時(shí)將sa_mask 指定的信號擱置。
sa_restorer 此參數(shù)沒有使用。
sa_flags 用來設(shè)置信號處理的其他相關(guān)操作,下列的數(shù)值可用。
OR 運(yùn)算(|)組合
A_NOCLDSTOP : 如果參數(shù)signum為SIGCHLD,則當(dāng)子進(jìn)程暫停時(shí)并不會通知父進(jìn)程
SA_ONESHOT/SA_RESETHAND:當(dāng)調(diào)用新的信號處理函數(shù)前,將此信號處理方式改為系統(tǒng)預(yù)設(shè)的方式。
SA_RESTART:被信號中斷的系統(tǒng)調(diào)用會自行重啟
SA_NOMASK/SA_NODEFER:在處理此信號未結(jié)束前不理會此信號的再次到來。
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set,int signo);
int sigdelset(sigset_t *set,int signo);
int sigismember(sigset_t *set,int signo);
int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
sigemptyset函數(shù)初始化信號集合set,將set設(shè)置為空.sigfillset也初始化信號集合,只是將信號集合設(shè)置為所有信號的集合.sigaddset將信號signo加入到信號集合之中,sigdelset將信號從信號集合中刪除.sigismember查詢信號是否在信號集合之中.
sigprocmask是最為關(guān)鍵的一個(gè)函數(shù).在使用之前要先設(shè)置好信號集合set.這個(gè)函數(shù)的作用是將指定的信號集合set加入到進(jìn)程的信號阻塞集合之中去,如果提供了oset那么當(dāng)前的進(jìn)程信號阻塞集合將會保存在oset里面.參數(shù)how決定函數(shù)的操作方式.
SIG_BLOCK:增加一個(gè)信號集合到當(dāng)前進(jìn)程的阻塞集合之中.
SIG_UNBLOCK:從當(dāng)前的阻塞集合之中刪除一個(gè)信號集合.
SIG_SETMASK:將當(dāng)前的信號集合設(shè)置為信號阻塞集合.
評論
查看更多