Linux环境编程之信号处理(一)

        已经有差不多一年没有使用 《unix环境高级编程》中的知识了,现在抽个时间大概的复习下《unix环境高级编程》,也顺便记录下,方便以后再复习使用;


信号简介

        1、信号是软件中断,提供的是一种处理异步事件的方法;
        2、不存在编号为0的信号,在kill函数中对信号0有特殊应用;
        3、对信号的处理方法有三种:
              a、忽略信号,也就是不做任何处理,SIGKILL/SIGSTOP(即:9/19号信号)不能被忽略;

              b、捕捉信号,也就是调用用户开始设计好的信号处理函数去处理;9/19号信号不能被捕捉;

              c、系统默认,不做处理,也不设置默认,调用系统定义的处理该信号的方法去执行;(绝大部分默认为终止该进程)

        4、可以调用命令:kill -l  来查看系统支持的信号;2号信号 ---- ctrl+c ---- SIGINT;20号信号 ---- ctrl+z ---- SIGTSTP;


signal函数

        signal函数原型:void  (*signal(int signo, void (*func)(int) ) ) (int);

        该函数的功能:当信号signo 发生时,调用 func 函数去处理;其实就是对signo的信号进行绑定;

        函数分析:

        void (*func)(int) 这是一个函数指针,其实就是表示一个函数的入口地址,当信号发生时,跳转到该入口地址去执行;

        signo 是信号的编号,指定某个信号;

        所以:signal的函数为   signal(int signo,  void  (*func)(int)) ;我们一般使用的时候也是这样用的,例如:signal(SIGINT, faction);对SIGINT信号进行绑定;

        那为什么上面的原型不一样呢,那是因为上面的原型是包括了返回值,而signal的返回值是一个函数指针,带有int参数,返回值为空  的函数指针;其实返回的函数指针就是该信号前一个绑定的处理函数指针;

        看下面的程序,能够很好的理解signal函数:

 #include<signal.h>
 #include<stdio.h>
 
 void sigFaction(int signo)// 第一次为SIGINT信号绑定的处理函数
 {
     if (signo == 100) // 这里signo不是代表信号,是为了测试signal返回函数指针用的
         printf("signal ret!\n");
     
     if (signo == SIGINT)// 这里是测试SIGINT信号处理方法
         printf("ctrl + c\n");
 }
 
 void test(int signo)// 第二次为SIGINT信号绑定的处理函数
 {
     if (signo == SIGINT)
         printf("test\n");
 }
 
 int main(void)
 {
     if (SIG_ERR == signal(SIGINT, sigFaction) )// 第一次开始为SIGINT信号进行绑定
         printf("sigint error!\n");// 出错打印
 
     sleep(10);// 睡眠会,期间发生ctrl+c 则会调用上面绑定的sigFaction函数进行处理
 
     signal(SIGINT, test)(100);// 这里利用signal()函数返回上一次绑定的函数指针,进行调用sigFaction()函数,传入的参数为100;同时为SIGINT绑定test处理函数
 
     while(1) pause();// 为了等待信号发生,避免进程终止
 
     return 0;
 }

        代码分析:

        设计这个代码主要是分析signal()函数原型,第一次为信号SIGINT绑定了sigFaction()函数,当ctrl+c发生时,会调用sigFaction()函数来进行处理的;

        然后执行 signal(SIGINT, test)(100); 因为signal()函数返回的是上一次为该信号绑定的处理函数指针,所以这里顺便调用下上一次绑定处理函数,传入参数为 100,所以在sigFaction()函数中会打印相应的信息;

        同时,这里也会为SIGINT信号进行第二次绑定test处理函数。那么当ctrl + c再次发生时,就会调用test()函数来进行处理了;

运行结果:

        

        注意:在调试信号程序时,建议还是先看看http://blog.csdn.net/yuzhihui_no1/article/details/44564963,这样会很方便调试;


简化理解

        如果上面对signal原型分析的还不能理解的话可以试试用typedef来简化下;

        根据上面代码:typedef  void sigPoint(int);  这里把  void xxx(int)类型的函数统一为  sigPoint函数; 

        则:void  (*signal(int signo, void (*func)(int) ) ) (int);  ====  sigPoint  *signal(int, sigPoint*);


信号系统处理函数

        上面已经说过,对信号响应有三种情况;第一、忽略该信号;第二、捕捉该信号;第三、执行系统默认动作;第二种 捕捉该信号,上面已经讲过,当捕捉到该信号后,执行用户最开始设置好的处理函数;
        第一种,忽略该信号,则是把 1强转为函数 SIG_IGN:#define SIG_IGN (void (*)())1;
        第三种,执行系统默认动作,则是把0强转为函数SIG_DFL:#define SIG_DFL (void (*)())0
        
        还有一个绑定出错的函数 SIG_ERR:#define SIG_ERR (void (*)()) -1;

         

        转载请注明作者和原文出处,原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/44748585

        若有不正确之处,望大家指正,共同学习!谢谢!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值