信號捕捉,防止進程意外死亡
- 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個實時信號支持排隊)
‘’’ -
內核實現信號捕捉過程