信號捕捉,防止進程意外死亡
- signal函數
man signal
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
參數介紹;
signum 要捕捉的信號
handler 要執行的捕捉函數指針,函數聲明 void func(int)
- sigaction函數
man sigaction
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
參數介紹:
signum 要捕捉的信號
act 傳入的動作
struct sigaction {void (*sa_handler)(int);//函數指針void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;//執行捕捉函數期間,臨時屏蔽的信號集int sa_flags; //一般用0(對應使用第一個函數指針),SA_SIGINFO會使用第二個函數指針void (*sa_restorer)(void); //無效參數
};
oldact 傳出參數,原有的動作
代碼示例:
使用 sigaction 捕捉setitimer發出的 14號信號:
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>void catch(int signum) {printf("catch sign num is %d\n", signum);
}
int main() {struct sigaction myact;myact.sa_handler = catch;sigemptyset(&(myact.sa_mask));myact.sa_flags = 0;sigaction(SIGALRM, &myact, NULL);struct itimerval itimer = {{3, 0},{2, 0} };setitimer(ITIMER_REAL, &itimer, NULL);while (1) {printf("la la la\n");sleep(1);}return 0;
}
-
信號捕捉的特性
‘’’
1.進程正常運行時,默認PCB中有一個信號屏蔽字,假定為☆,它決定了進程自動屏蔽哪些信號。當注冊了某個信號捕捉函數,捕捉到該信號以后,要調用該函數。而該函數有可能執行很長時間,在這期間所屏蔽的信號不由☆來指定。而是用sa_mask來指定。調用完信號處理函數,再恢復為☆。
2.XXX信號捕捉函數執行期間,XXX信號自動被屏蔽。
3.阻塞的常規信號不支持排隊,產生多次只記錄一次。(后32個實時信號支持排隊)
‘’’ -
內核實現信號捕捉過程
