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

来源:互联网 发布:抓取访客手机号源码 编辑:程序博客网 时间:2024/05/18 12:39

//参考了一些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
原创粉丝点击