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;
}
————————————————
原文链接:https://blog.csdn.net/cainiaohhf/article/details/47341677
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号