前言
在前文中,讲述了一个可靠信号的示例。它分成几个步骤组成( 请参考前文 )。在 Linux 系统编程中,有个方法可以将这些步骤给集成起来,让我们使用起来更加的方便。那就是调用 sigaction 函数。
sigaction 函数
原型:int sigaction (int signo, const struct sigaction * restrict act, struct sigaction *restrict oact)
作用:将信号及其处理函数关联起来,但这个注册函数中,信号处理函数是放在一个结构体中的,这个结构体除了注册函数,还可以存放一些其他信息,以实现可靠信号机制:
其中,第一个字段是信号处理函数的地址;第二个字段是在接收到所等待的信号前,需要屏蔽的信号的信号集( 从信号处理函数返回之后就会恢复到原先的信号屏蔽字 );
另外两个字段一般设置为 0 和 NULL,用的比较少。
最后一个参数如果非空责将返回这个信号原本对应的的信号处理结构体。
代码实现
下面程序是一个使用 sigaction 函数实现可靠信号的示例:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <signal.h> 4 5 static void sig_quit (int); 6 7 int main (void) { 8 9 // 初始化信号处理结构体 10 struct sigaction act; 11 act.sa_handler = sig_quit; 12 // 这一步可以根据需要,屏蔽指定的信号,其对应信号处理函数执行完毕以后,信号屏蔽字又会恢复到调用前的状态。 13 sigemptyset (&act.sa_mask); 14 act.sa_flags = 0; 15 act.sa_sigaction = NULL; 16 17 // 记得参数类型是引用类型! 18 if (sigaction (SIGQUIT, &act, NULL) < 0) { 19 printf ("注册信号处理函数失败 "); 20 return 1; 21 } 22 23 // 在此阶段进入信号处理函数并返回后,不会继续挂起状态,而是进入到下一条语句。 24 sleep (50); 25 26 return 0; 27 } 28 29 static void sig_quit (int signo) 30 { 31 printf("捕捉到退出信号 "); 32 33 // 将对退出信号的处理设置为关闭进程 34 if (signal (SIGQUIT, SIG_DFL) == SIG_ERR) { 35 printf("设置退出信号处理函数失败 "); 36 } 37 }
运行测试
发现了一个问题:未打印” 捕捉到退出信号 " ( 31 行 ),这个问题只能留待日后解决。
小结
sigaction 结构体的后两个参数的具体功能,请参阅相关资料。