sigaction() 使用

/** 
 * @file demo7.c
 * @Synopsis  
 *
 * int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)
 * @param signum
 * @param struct sigaction * oldact  -> NULL
 * @param const struct sigaction *act
 *

 * 注:阻塞的意思是延迟相应信号
 * sigaction,是为替代signal 来设计的较稳定的信号处理。
 * typedef void (*sighandler_t)(int);
 * sighandler_t signal(int signum,sighandler_t handler);
 * 不能完成的任务:{
 *  1:不知道信号产生的原因;
 *  2:处理信号中不能阻塞其他信号
 * }
 * 而signaction , 则可以设置比较多的信号消息。
 *                  尤其是在信号处理函数过程中接受信号,进行何种处理。
 *

 * sigaction 函数用于改变进程接收到特定信号后的行为。
 * 该函数的第一个参数为信号的值,可以为除SIGKILL 及SIGSTOP外的任何一个特定有效的信号(为
 *      这两个信号定义自己的处理函数,将导致信号安装错误)。
 * 第二个参数是指向结构sigaction 的一个实例的指针,在结构体sigaction的实例中,指定了对
 *      特定信号的处理,可以为空,进程会以缺省方式对信号处理;
 * 第三个参数oldact 指向的对象用来保存原来对应信号的处理,可指定oldact 为NULL.
 * 如果把第二,第三个参数都设为NULL,那么该函数可用于检查信号的有效性。
 * 第二个参数最为重要,其中包含了对指定信号的处理,信号所传递的信息,信号处理函数执行过程
 * 中应屏蔽掉哪些函数等等。
 *
 * struct sigaction{
 *  void (*sa_handler)(int);// like signal
 *  void (*sa_sigaction)(int,siginfo_t *,void *);// 
 *  sigset_t sa_mask;
 *  int sa_flags;
 *  void (*sa_restorer)(void);
 * }
 * 其中sa_restorer,己过时POSIX不支持它,不再使用它
 *

 * SIGKILL and SIGSTOP 这两个信号是不能屏蔽的。
 * 如果 sa_flags -> SA_SIGINFO....则会调用 sigaction
 * sa_mask 指出来一组信号,可以被阻塞。。
 *
 * sa_flags{
 *  SA_NODEFER
 *  SA_RESETHAND
 *  SA_RESTART
 *  SA_SIGINFO
 * }
 * sa_mask{
 *
 *  // 信号设置,信号集合,一堆信号。kill -l 
 *  // 小于 34的 叫普通信号
 *  // 大于等于34 叫实施信号
 *  // sigset_t 看成一个整数
 *  sigset_t{
 *      sigismember // 判断某一个信号是否在里面
 *      setfillset/sigdelset // 把所有位置位1,/把里面的某一个位删除设置0
 *      sigemptyset/sigaddset // 集合里面所有位清0 /把某一个清0
 *  }
 *  sigprocmask

 * }
 *
 * sigset_t s1;
 *       0 0 0 0 0 0 0 0 0
 * 集合:0 1 2 3 4 5 6 7 8
 *
 * s1 = 2;
 * 怎么样得到一个信号集合。。
 * 我们有一糸列的函数
 * 信号集合大于16
 * fill 往后面减。
 * 小于16个信号
 * 清空往里面加
 * 不同糸统作法不一样。。
 *
 * signal 间接调用 sigaction
 * @author MrClimb
 * @version 1.1.0
 * @date 2012-05-20
 */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#define INPUTLEN 100
void inthandler();

int main(int argc, char **argv)
{
    struct sigaction newhandler;
    sigset_t blocked;// 信号集合
    char x[INPUTLEN];

    newhandler.sa_handler = inthandler;
    // 不加SA_NODEFER 只处理一次性号。
    // 而加上则每次信号都将处理。
    // newhandler.sa_flags = SA_RESTART;// ^C 只接收一次性号。连续按不接收; 设置 0 也可以;

    // 3)当上面去掉了SA_NODEFER标志位。程序在执行信号处理函数过程中,^C信号将会被阻止,
    // 但是执行信号处理函数期发送的^C信号将会被阻塞,知道信号处理函数执行完成,才有机会处理
    // 信号函数执行期间产生的^C,但是在信号函数执行产生的多次^C,最后只产生^C
    // 而下面设置了SA_NODEFER,^C信号将不会被阻塞。所以能够并行执行下次的信号处理函数。
    // newhandler.sa_flags = SA_RESTART | SA_NODEFER;// ^C 连续按每一次都接收(程序都不会结束)
    
    // 1)第一次产生^C 信号时候,该信号被自己设定的信号处理函数时行了处理。在处理过程中,
    // 由于这里设定了SA_RESETHAND标志位,又将该信号的处理函数设置为默认的信号处理
    // 函数(糸统默认的处理方式为IGN),所以在第二次发送^C信号的时候,是由默认的信号
    // 算是函数处理的,导致程序结束,
    // 2) 当根据上面没有SA_RESETHAND标志位,导致程序中所有的^C信号均是由我们自己的信号
    // 处理函数来进行处理,所以我们发关多少次^C信号程序都不会退出
    newhandler.sa_flags = SA_RESTART | SA_NODEFER | SA_RESETHAND;// ^C 按一次执行,按第二次^C 则停止该进程

    sigemptyset(&blocked);

    sigaddset(&blocked,SIGQUIT);// 往集合里加一个SIGQUIT 信号(^\)
    sigaddset(&blocked,SIGTSTP);// 添加 终止信号 ^Z 
   /**
    * sa_mask 在信号处理函数运行时 屏蔽所有的信号除了SIGSTOP & SIGKILL 两个信号外,
    * 当然上面blocked 信号被置空了,重新设置了上面两个信号,当接收到上面两个信号,则
    * 执行屏蔽操作,退出程序。
    */

    newhandler.sa_mask = blocked;// 将blocked 传给 sa_mask 时,它才屏蔽后一个信号
   

    if(sigaction(SIGINT,&newhandler,NULL)== -1)
    {
        perror("sigaction");
    }else
    {
        while(1)
        {
            fgets(x,INPUTLEN,stdin);
            printf("input: %s",x);
        }
    }
    return 0;
}
void inthandler(int s)
{
    printf("Called with signal %d\n",s);
    sleep(s*3);
    printf("done handling signal %d\n",s);
}


原文:http://mrjake.blog.163.com/blog/static/10510910620124223322168/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值