sigaction实例

来源:互联网 发布:数据库oracle考试 编辑:程序博客网 时间:2024/05/16 11:50

出处:http://hi.baidu.com/xu_zhisheng/blog/item/82cbdfd7ab12872607088bdc.html#0

 

转载+原创

加上自己的总结与程序的调试并验证!

 

#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 < 10; 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;    sigemptyset(&act.sa_mask);    sigaddset(&act.sa_mask, SIGQUIT); //将SIGQUIT(Ctrl+\)信号加入信号集     // sigaddset(&act.sa_mask, SIGINT);  //将SIGINT(Ctrl+C)信号加入信号集    /***(2)if signal got,then set to the signal to SIG_DFL(the default signal)        and the signal occur immediately.***/    act.sa_flags = SA_RESETHAND | SA_NODEFER;    //act.sa_flags = 0; //(3)    /*This can be used for add sigset mask,and then block the signal SIGOUIT or SIGINT*/    //sigprocmask(SIG_BLOCK,&act.sa_mask,NULL);    sigaction(SIGINT, &act, &oldact);    while(1) {        sleep(1);        printf("sleeping %d\n", i);        i++;    }}


 

(一)在act.sa_flags = SA_RESETHAND | SA_NODEFER的情况下

 

#gcc -g -o text_sigaction text_sigaction.c

 

执行结果如下:

/********************(1)*********************/

#./text_sigaction
sleeping 0                   
sleeping 1
sleeping 2
I got signal 2               /***Ctrl+C***/      
i = 0
i = 1
i = 2           /**Ctrl+C****/         /****因为 act.sa_flags = SA_RESETHAND | SA_NODEFER;

                                     一句,表明:Ctrl+C 的信号恢复到系统的默认状态,

                                  且执行该信号不延迟,不再进入信号处理中执行了!***/<---------见注释(1)

#

 

/**********************(2)********************/

#./text_sigaction

sleeping 0
sleeping 1
sleeping 2
I got signal 2     /**Ctrl+C**/     该信号恢复到默认状态,且不延迟。
i = 0
i = 1
i = 2
i = 3                 /***Ctrl+\**/      SIGQUIT信号阻塞!<--------------------见注释(2)
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
退出

#

 

/*************(3)*******************/

#./text_sigaction
sleeping 0
sleeping 1
sleeping 2
sleeping 3
sleeping 4            /***Ctrl+\**/    信号直接退出。
退出

#

 

/*******************(4)***************/

#./text_sigaction
sleeping 0
sleeping 1
sleeping 2
I got signal 2     /***Ctrl+C***/     /***第一次进入信号处理函数,且该信号变为默认,且不延迟*****/
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
sleeping 3
sleeping 4
sleeping 5    /****Ctrl+C***/    /***第二次不进入信号处理函数,而是执行系统的该信号的默认情况***/

#

 

注释(1)

       第二次"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。

 

(二)在act.sa_flags = SA_RESETHAND | SA_NODEFER;------->act.sa_flags =SA_NODEFER;的情况下;

 

#./text_sigaction1
sleeping 0
sleeping 1
sleeping 2
sleeping 3
I got signal 2      /**Ctrl+C***/
i = 0
i = 1
i = 2
I got signal 2     /**Ctrl+C**/
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5                   <---------- 可见是将Ctrl+C的信号压入队列!!

i = 3
i = 4
i = 5
sleeping 4
sleeping 5      /**Ctrl+\**/
退出
#

 

 

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清零后可能会造成信号丢失!

 

注: 阻塞的意思是延迟相应信号

原创粉丝点击