sigaction()函数。它的原型为:
#include <signal.h>
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
sigaction结构体:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sa_sigaction:如果设置了SA_SIGINFO标志位,则会使用sa_sigaction处理函数,否则使用sa_handler处理函数。
sa_mask:定义一组信号,在调用由sa_handler所定义的处理器程序时将阻塞该组信号,不允许它们中断此处理器程序的执行。
sa_flags:位掩码,指定用于控制信号处理过程的各种选项。
SA_NODEFER:捕获该信号时,不会在执行处理器程序时将该信号自动添加到进程掩码中。
SA_ONSTACK:针对此信号调用处理器函数时,使用了由sigaltstack()安装的备选栈。
SA_RESETHAND:当捕获该信号时,会在调用处理器函数之前将信号处置重置为默认值(即SIG_IGN)。
SA_SIGINFO:调用信号处理器程序时携带了额外参数,其中提供了关于信号的深入信息
SA_RESTART:执行信号处理后自动重启动先前中断的系统调用
sigaction()的功能是为信号指定相关的处理程序,但是它在执行信号处理程序时,会把当前信号加入到进程的信号屏蔽字中,从而防止在进行信号处理期间信号丢失。
sa_flags用于指定信号处理动的选项标志,详见手册。这里我想说的是SA_RESTART和SA_SIGINFO。SA_RESTART用于控制信号的自动重启动机制,如前面例子所示,对signal(),Linux默认会自动重启动被中断的系统调用;而对于 sigaction(),Linux默认并不会自动重启动,所以如果希望执行信号处理后自动重启动先前中断的系统调用,就需要为sa_flags指定 SA_RESTART标志。
程序:
如果改为act.sa_flags = (SA_SIGINFO|SA_RESETHAND),信号处理一次就会退出;
#define SIGETX 44
void signalHandle(int signum) {
if(signum = SIGETX) {
printf("SIGETX recived");
}
}
int main(void)
struct sigaction act;
sigemptyset(&act.sa_mask);
//这里使用SA_RESTART执行信号处理后自动重启到先前中断的系统调用,可以多次捕捉信号
act.sa_flags = (SA_SIGINFO|SA_RESTART);
act.sa_sigaction = signalHandle;
sigaction(SIGETX, &act, NULL);
while(1){
pause();
}