signal学习代码实例(sigaction/signalfd)

//参考了一些blog:
//1、http://cpp.ezbty.org/import_doc/linux_manpage/signalfd4.2.html
//2、http://www.cnblogs.com/wblyuyang/archive/2012/11/13/2768923.html
//3、http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html

</pre><pre name="code" class="cpp">#include <sys/signalfd.h>//signalfd;
#include <signal.h>//sigemptyset
#include <unistd.h>//exit;read;
#include <stdlib.h>//
#include <stdio.h>

inline void handle_error(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

void test_singal_pause();

void test_signalfd();

void test_signal_block();

void test_signalfd()
{
    sigset_t mask;
    int sfd;
    struct signalfd_siginfo fdsi;
    ssize_t s;

    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);

    /* 阻塞信号以使得它们不被默认的处理试方式处理 */

    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
        handle_error("sigprocmask");
    //signalfd应该会取消block;否则的话,信号是无法捕获的.
    sfd = signalfd(-1, &mask, 0);
    if (sfd == -1)
        handle_error("signalfd");
    //这里是位了测试,如果延迟了,任然会记录下来,不会丢失.但是,同一个信号,最多保存一次.
    sleep(3);
    printf("Sleep over\n");
    for (;;) {
        s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
        if (s != sizeof(struct signalfd_siginfo))
            handle_error("read");

        if (fdsi.ssi_signo == SIGINT) {
            printf("Got SIGINT\n");
        } else if (fdsi.ssi_signo == SIGQUIT) {
            printf("Got SIGQUIT\n");
            exit(EXIT_SUCCESS);
        } else {
            printf("Read unexpected signal\n");
        }
    }
}
//------------------------------------------------------------------------------------
void singal_process(int sig)
{
    switch(sig)
    {
    case SIGINT:
    {
        printf("sig=SIGINT\n");
        break;
    }
    case SIGQUIT:
    {
        printf("sig=SIGQUIT\n");
        break;
    }
    case SIGTSTP:
    {
        printf("sig=SIGTSTP\n");
        break;
    }
    default :
    {
        printf("Unknow signal:%d!\n",sig);
    }
    }
}

void test_signal_block()
{
    //1-set signal;
    sigset_t mask;
    sigset_t oldmask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);
    sigaddset(&mask, SIGTSTP);
    //2-block the signal;
    if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
    {
        handle_error("sigprocmask");
    }
    //
    struct sigaction act, oldact;
    act.sa_handler = singal_process;
    //这里是mask set似乎没什么用;act顾名思义,是用来设置动作的(即指针函数).
    //sigaddset(&act.sa_mask, SIGQUIT);
    //sigaddset(&act.sa_mask, SIGINT);
    //sigaddset(&act.sa_mask, SIGTSTP);
    //act.sa_flags = SA_RESETHAND | SA_NODEFER;
    act.sa_flags = 0;
    //这里才是真正的信号注册;
    sigaction(SIGINT, &act, &oldact);
    sigaction(SIGQUIT, &act, &oldact);
    sigaction(SIGTSTP, &act, &oldact);
    printf("1-sleep\n");
    sleep(3);

    if (sigprocmask(SIG_SETMASK, &oldmask,NULL) == -1)
    {
        handle_error("sigprocmask");
    }
    //sigsuspend这个函数,主要替换pause+信号的效果.
    printf("2-sleep\n");
    sleep(3);
}
//------------------------------------------------------------------------------------
void test_singal_pause()
{
    sigset_t newset;
    sigset_t  old;
    struct sigaction act;
    act.sa_handler = singal_process;  //信号处理函数handler
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGINT, &act, 0);  //准备捕捉SIGINT信号
    sigemptyset(&newset);
    sigaddset(&newset, SIGINT);
    sigprocmask(SIG_BLOCK, &newset, &old);  //将SIGINT信号阻塞,同时保存当前信号集
    printf("Blocked");
    sigprocmask(SIG_SETMASK, &old, NULL);  //取消阻塞:注意,一定要取消block,否则会捕获不到信号.
    pause();
}


int main()
{
    //test_singal_pause();
    test_signalfd();
    //test_signal_block();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值