- struct sigaction{
- void (*sa_handler)(int);
- //在调用前加入信号屏蔽字,仅当信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值*/
- sigset_t sa_mask;
- //Signal options
- int flags;
- //结构中还有一个参数,不懂。
- }
- #include <stdio.h>
- #include <signal.h>
- #include <unistd.h>
- void show_handler(int sig)
- {
- printf("I got signal %d\n", sig);
- int i;
- for(i = 0; i < 5; i++) {
- printf("i = %d\n", i);
- sleep(1); //for inputting interupt signal
- }
- }
- int main(void)
- {
- int i = 0;
- struct sigaction act, oldact;
- act.sa_handler = show_handler;
- sigaddset(&act.sa_mask, SIGQUIT); //(1)加入信号集,屏蔽"CTRL+\"
- act.sa_flags = SA_RESETHAND | SA_NODEFER; //(2)if signal got,set to SIG_DFL
- //act.sa_flags = 0; //(3)
- //sigprocmask(SIG_BLOCK,&act.sa_mask,NULL);/*This can be used for add sigset mask*/
- sigaction(SIGINT, &act, &oldact);
- while(1) {
- sleep(1);
- printf("sleeping %d\n", i);
- i++;
- }
- }
结果如下:
(1)第一种情况,执行"CTRL+C", 在中断处理函数后再执行"CTRL+C"
$./a.out
sleeping 0
I got signal 2 /*CTRL+C*/
i = 0
i = 1
i = 2
i = 3
i = 4
sleeping 1
sleeping 2
sleeping 3
sleeping 4 /*CTRL+C结束*/
说明:第二次"CTRL+C",由于act.sa_flags = SA_RESETHAND | SA_NODEFER 。SA_RESETHAND: 信号发给进程后,把信号处理器复位为缺省值SIG_DFL,所以第二次按"Ctrl+C"时, 信号处理器已经复位为SIG_DFL,对SIGINT来说,缺省动作就是终止进程。
(2)注:如果在信号SIGINT(Ctrl + C)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+\),将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT,见如下结果
$./a.out
sleeping 0
sleeping 1
I got signal 2 /*CTRL+C*/
i = 0
i = 1
i = 2 /*CTRL+\*/
i = 3
i = 4
Quit
(3)第三种情况:"CTRL+C", "CTRL+C", "CTRL+\"
改act.sa_flags = SA_RESETHAND | SA_NODEFER;->act.sa_flags =SA_NODEFER;
[root@FPC10 zhisxu]# ./a.out
sleeping 0
I got signal 2 /*CTRL+C*/
i = 0
i = 1
I got signal 2 /*CTRL+C*/
i = 0
i = 1 /*somewhere here*/
i = 2 /*CTRL+\*/
i = 3
i = 4
i = 2
i = 3
i = 4
Quit
sigaction.sa_flags 控制内核对该信号的处理标记
SA_NODEFER 一般情况下, 当信号处理函数运行时,内核将阻塞<该给定信号 -- SIGINT>。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字)
SA_RESETHAND 当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般不用这个名字)
SA_SIGINFO 信号处理函数是带有三个参数的sa_sigaction
*** 如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(无须设置sa_flags标志),那么必须将sa_flags清零,否则运行将会产生段错误。但是sa_flags清零后可能会造成信号丢失!
注: 阻塞的意思是延迟相应信号
原文地址:http://hi.baidu.com/xu_zhisheng/blog/item/82cbdfd7ab12872607088bdc.html