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();
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐