Linux信号量函数signal和sigaction详解

  1. signal函数
    1.1 函数指针
    void (*func)(int)
    
    上述的func是一个函数指针,可以指定所有返回类型为void参数类型为int的所有函数,和指针本质上并没有什么区别,在内存空间上都是指向一个特定的地址。函数指针的意义类似于C++语言当中的类,类是具有同一种性质事物的集合,现实生活中的许多事物我们都可以抽象成对应的类,C++相较于C语言而言,扩展了面向对象的部分,面向对象的主要功能就是为了更好地将事物进行模块化,从这个角度上出发,函数指针出现的意义应该也差不多(扯远啦~,以后有时间我再具体讨论这两门语言)
    例如:
    void catNum(int num){
    	cout << "the count of cat is" << num <<  endl;
    }
    void dagNum(int num){
    	cout << "the count of dog is" << num <<  endl;
    }
    func = catNum;
    func(5); //输出:the count of cat is 5
    func = dogNum;
    func(4); //输出:the count of dog is 4
    
    void (*fun(int))(int)
    
    这里用了fun(int)替代了func,这个声明参数类型为int的fun函数返回一个指向参数类型为int,返回值类型为void的函数指针
    1.2. signal函数解析
    函数原型:void (*signal(int signo, void (*handle)(int))) (int)
    
    我们可以分解来看:
    1. void (*handle) (int) —>指向返回值类型为void,参数类型为int的函数
    2. signal(int signo, void (*handle)(int))—>第一个参数为int,第二个参数为函数指针,返回值类型为指向返回值类型为void,参数类型为int的函数指针
    3. 综合来看,我们可以简化为以下形式:
      typedef void(*handle)(int)
      handle signal(int signo, handle)
      
      整个函数的功能为:根据signo信号量执行相对应的信号处理函数,即handle函数,具体运行实例:
      #include <stdio.h>
      #include <unistd.h>
      #include <signal.h>
      
      void timeout(int sig){ //handle函数
          if (sig == SIGALRM) puts("Time out !");
          alarm(2);
      }
      void keycontrol(int sig){ //handle函数
          if (sig == SIGINT){
              puts("DTRL + C pressed");
          }
      }
      
      int main(int argc, char* argv[]){
          int i;
          signal(SIGALRM, timeout); //SIGALRM信号量-----alarm函数触发
          signal(SIGINT, keycontrol); //SIGINT信号量----Ctrl+C触发
          alarm(2);
      
          for (int i = 0; i < 3; ++i){
              puts("wait...");
              sleep(100);
          }
          return 0;
      }
      
  2. sigaction函数
    sigaction函数是signal函数的改进版,signal函数定义复杂,不太好理解,功能也比较局限,只能传递信号量,而不能对信号量进行相关的设置,同时只能对当前的状态进行处理,无法记录之前的状态
    2.1sigaction函数参数解析
    int sigaction(int signo, const struct sigaction* act, struct sigaction* oldact)
    
    sigaction结构体定义如下:
    struct sigaction
    {
    	void (*sa_handler)(int); //即信号量响应处理函数
    	sigset_t sa_mask; //指定信号相关选项和特性
    	int sa_flags; //指定信号相关选项和特性
    }
    typedef struct 
    {
      unsigned long sig[_NSIG_WORDS]; //无符号整数数组,linux中long为4个字节
    } sigset_t;
    
    整体上看,sigaction函数比signal函数功能更为强大,同时也比较好理解,更为关键的是可以对之前响应过的处理进行操作,实际上,sigaction比signal函数更为常用
    具体运行实例:
    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    
    void timeout(int sig){ //信号响应处理函数
        if (sig == SIGALRM) puts("Time out !");
        alarm(2);
    }
    int main(int argc, char* argv[]){
        int i;
        struct sigaction act;
        act.sa_handler = timeout;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGALRM, &act, 0);
        alarm(2);
    
        for (int i = 0; i < 3; ++i){
            puts("wait...");
            sleep(100);
        }
        return 0;
    }
    

[1]https://blog.csdn.net/imxiangzi/article/details/7584917
[2]https://blog.csdn.net/ta893115871/article/details/7475095
[3]《TCP/IP网络编程》—尹圣雨

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用和提供了关于signal函数的两种用法的示例代码。signal函数是一个用来处理信号函数,其原型为sigaction(int signum, const struct sigaction* act, struct sigaction* oldact)。参数signum表示要处理的信号的编号,act是一个指向结构体sigaction的指针,用来指定信号处理函数,oldact是一个指向结构体sigaction的指针,用来保存之前的信号处理函数signal函数在接收到指定的信号时,会调用act所指定的信号处理函数。 在引用的示例代码中,signal(SIGINT, SIG_IGN)表示忽略了SIGINT信号,即在接收到SIGINT信号时不做任何处理,程序会一直运行下去。 在引用的示例代码中,signal(SIGINT, signal_handler_fun)表示在接收到SIGINT信号时,会调用signal_handler_fun函数来处理该信号signal_handler_fun是一个自定义的函数,其作用是输出"aaa"并换行。 除了signal函数外,还有一个同名的命令行工具/bin/kill可以用来向指定进程发送信号。例如,/bin/kill -9 15213表示向进程编号为15213的进程发送信号9。 综上所述,signal函数用来处理信号,可以通过指定信号处理函数来对接收到的信号做出相应的操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Signal ()函数详细介绍](https://blog.csdn.net/qq_58011370/article/details/119456193)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Unix信号详解Signal信号说明)](https://blog.csdn.net/github_33873969/article/details/77744382)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值