信号捕捉,防止进程意外死亡
- 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个实时信号支持排队)
‘’’ -
内核实现信号捕捉过程