• 信号之sigaction函数


    可靠机制,不会恢复默认信号处理程序:

    新的信号安装函数sigaction:sigaction函数用于改变进程收到的特定信号后的行为
      int sigaction(int signum,const struct sigaction *act,const struct sigaction *old); //成功返回0,失败返回-1

      struct sigaction{
        void (*sa_handler)(int);

        sigset_t sa_mask;//屏蔽集合
        int sa_flags;
        //可选
        void (*sa_sigaction) (int,siginfo_t*,void*) //与void (*sa_handler)(int)任选其一,这个针对可靠信号
      }
    1、第一个参数为信号的值,可以为除SIGKILL以及SIGSTOP外的任何一个特定有效的信号;
    2、第二个参数是一个指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定
    信号的处理,可以为空,进程会以缺省的方式对信号处理;这个结构体包含了对指定信号的处理,信号传导的信息,信号处理函数执行过程中应屏蔽掉哪些函数。
    3、第三个参数oldact指向的对象用来保存原来对应信号的处理函数,可以指定oldact为NULL

    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<errno.h>
    #include<string.h>
    
    #include<signal.h>
    #define ERR_EXIT(m)
        do
        {
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)  //宏要求一条语句
    void handler(int sig);
    int main(int argc,char*argv[])
    {
        struct sigaction act;
        act.sa_handler=handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        if(sigaction(SIGINT,&act,NULL)<0)
            ERR_EXIT("sigaction error
    ");
        for(;;)
            pause();
        return 0;
    }
    
    void handler(int sig)//sig是signum
    {    
        printf("receive a sig=%d
    ",sig);
    }

    linux中signal建立在可靠机制之上(信号在安装完,执行处理函数后,信号处理函数不会自动恢复到默认),用sigaction来模拟实现signal:

    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<errno.h>
    #include<string.h>
    
    #include<signal.h>
    #define ERR_EXIT(m)
        do
        {
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)  //宏要求一条语句
    void handler(int sig);
    __sighandler_t my_signal(int sig,__sighandler_t handler);
    int main(int argc,char*argv[])
    {
        struct sigaction act;
        act.sa_handler=handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
    //    if(sigaction(SIGINT,&act,NULL)<0)
    //        ERR_EXIT("sigaction error
    ");
        my_signal(SIGINT,handler);
        for(;;)
            pause();
        return 0;
    }
    __sighandler_t my_signal(int sig,__sighandler_t handler)//signal出错返回SIG_ERR
    {
        struct sigaction act;
        struct sigaction oldact;
        act.sa_handler=handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        if(sigaction(sig,&act,&oldact)<0)
            return SIG_ERR;
        return oldact.sa_handler;
    
    }
    
    void handler(int sig)//sig是signum
    {    
        printf("receive a sig=%d
    ",sig);
    }

    sigaction 中sa_mask:指定信号屏蔽字(调用信号处理函数所在的线程的信号屏蔽字中)其他信号如果在信号处理程序过程中到来,则它们会在信号处理函数执行时被阻塞。等到信号处理函数运行完,被屏蔽的信号才会递达。不同于sigprocmask,sigprocmask阻塞的信号,根本不会递达, 只会处于未决状态,不会执行信号处理程序。

     1 #include<unistd.h>
     2 #include<sys/types.h>
     3 #include<sys/stat.h>
     4 #include<fcntl.h>
     5 #include<stdlib.h>
     6 #include<stdio.h>
     7 #include<errno.h>
     8 #include<string.h>
     9 
    10 #include<signal.h>
    11 #define ERR_EXIT(m)
    12     do
    13     {
    14         perror(m);
    15         exit(EXIT_FAILURE);
    16     }while(0)  //宏要求一条语句
    17 void handler(int sig);
    18 int main(int argc,char*argv[])
    19 {
    20     struct sigaction act;
    21     act.sa_handler=handler;
    22     sigemptyset(&act.sa_mask);
    23     act.sa_flags=0;
    24     
    25     sigaddset(&act.sa_mask,SIGQUIT);
    26     if(sigaction(SIGINT,&act,NULL)<0)//若不指定sa_mask,若指定的话,SIGQUIT信号在SIGINT处理程序执行期间都被阻塞。
    27         ERR_EXIT("sigaction error
    ");
    28     for(;;)
    29         pause();
    30     return 0;
    31 }
    32 
    33 void handler(int sig)//sig是signum。信号处理函数过程中,屏蔽sa_mask
    34 {    
    35     printf("receive a sig=%d
    ",sig);
    36     sleep(5);//不设置sa_mask的话,未返回时按ctrl+直接退出,不能阻塞新的信号。阻塞结束,SIGQUIT信号递达
    37 }
  • 相关阅读:
    小白必读:闲话HTTP短连接中的Session和Token
    网络编程懒人入门(六):深入浅出,全面理解HTTP协议
    IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?
    致我们再也回不去的 Github ...
    了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化
    网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
    盘点微信的前世今生,微信成功的必然和偶然
    微信七年回顾:历经多少质疑和差评,才配拥有今天的强大
    写给小白的实时音视频技术入门提纲
    jenkins使用jacoco插件检测代码覆盖率(八)
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/8367125.html
Copyright © 2020-2023  润新知