使用 signal 函數處理時,只需把要處理的信號和處理函數列出即可。它主要是用於前 32 種非實時信號的處理,不支持信號傳遞信息,但是由於使用簡單、易於理解,因此也受到很 多程序員的歡迎。
一、signal()函數
下面只給出使用signal()函數的代碼示例:
#include
#include
#include
/*自定義信號處理函數*/
void my_func(int sign_no){
if(sign_no == SIGINT)
printf("I have get SIGINT\n");
else if(sign_no == SIGQUIT)
printf("I have get SIGQUIT\n");
}
int main(){
printf("Waiting for signal SIGINT or SIGQUIT \n ");
/*發出相應的信號,並跳轉到信號處理函數處*/
signal(SIGINT, my_func);
signal(SIGQUIT, my_func);
pause();
exit(0);
}
二、信號集函數組
使用信號集函數組處理信號時涉及一系列的函數,這些函數按照調用的先後次序可分爲以下幾大功能模塊:創建信號集合、登記信號處理器以及檢測信號。其中,創建信號集合主要用於創建用戶感興趣的信號,其函數包括以下幾個。
sigemptyset:初始化信號集合爲空。
sigfillset:初始化信號集合爲所有信號的集合。
sigaddset:將指定信號加入到信號集合中去。
sigdelset:將指定信號從信號集中刪去。
sigismember:查詢指定信號是否在信號集合之中。
登記信號處理器主要用於決定進程如何處理信號。這裏要注意的是,信號集裏的信號並不是真正可以處理的信號,只有當信號的狀態處於非阻塞狀態時才真正起作用。因此,首先就要判斷出當前阻塞能不能傳遞給該信號的信號集。這裏首先使用 sigprocmask 函數判斷檢測或更改信號屏蔽字,然後使用 sigaction 函數用於改變進程接收到特定信號之後的行爲。檢測信號是信號處理的後續步驟,但不是必須的。由於內核可以在任何時刻向某一進程發出信號,因此,若該進程必須保持非中斷狀態且希望將某些信號阻塞,這些信號就處於“未決”狀態(也就是進程不清楚它的存在)。所以,在希望保持非中斷進程完成相應的任務之後,就應該將這些信號解除阻塞。Sigpending 函數就允許進程檢測“未決”信號,並進一步決定對它們作何處理。
下面是信號集函數組的示例代碼:
#include
#include
#include
#include
#include
void my_func(int signum){
printf("If you want to quit, please try SIGQUIT\n");
}
int main(){
sigset_t set, pendset;
struct sigaction action1, action2;
int tst_fd;
/*創建信號集合,把信號SIGQUIT和SIGINT加到信號集合中*/
if(sigemptyset(&set) < 0)
perror("sigemptyset");
if(sigaddset(&set, SIGQUIT) < 0)
perror("sigaddset");
if(sigaddset(&set, SIGINT) < 0)
perror("sigaddset");
/*登記信號處理器,主要用於決定進程如何處理信號,**
**首先使用sigprocmask()函數判斷檢測或更改信號屏 **
**蔽字,然後用sigaction()函數改變進程接收到特定 **
**信號之後的行爲。檢測信號是信號處理的後續步驟,**
**但不是必須的。 */
//if(sigprocmask(SIG_BLOCK, &set, NULL) < 0)
//perror("sigprocmask");
//else{
//printf("blocked\n");
//sleep(1);
//}
if(sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)
perror("sigprocmask");
else
while(1){
tst_fd = sigismember(&set, SIGINT);
//printf("tst_fd is %d\n", tst_fd);
if(tst_fd > 0){
sigemptyset(&action1.sa_mask);
action1.sa_handler = my_func;
sigaction(SIGINT, &action1, NULL);
}
else if(sigismember(&set, SIGQUIT)){
sigemptyset(&action2.sa_mask);
action2.sa_handler = SIG_DFL;
sigaction(SIGTERM, &action2, NULL);
}
}
}