• linux c 之signal 和sigaction区别


    http://blog.csdn.net/muge0913/article/details/7331129

    要对一个信号进行处理,就需要给出此信号发生时系统所调用的处理函数。可以对一个特定的信号(除去SIGKILL和SIGSTOP信号)注册相应的处理函数。注册某个信号的处理函数后,当进程接收到此信号时,无论进程处于何种状态,就会停下当前的任务去执行此信号的处理函数。

    1、注册信号函数。

    1. #include<signal.h>  
    2.   
    3. void(*signal(int signumber,void ((*func)(int))(int)  

    signumber表示信号处理函数对应的信号。func是一个函数指针。此函数有一整型参数,并返回void型。其实func还可以取其他定值如:SIG_IGN,SIG_DFL.

    SIG_IGN表示:忽略signumber所指出的信号。SIG_DFL表示表示调用系统默认的处理函数。signal函数的返回值类型同参数func,是一个指向某个返回值为空并带有一个整型参数的函数指针。其正确返回值应为上次该信号的处理函数。错误返回SIG_ERR

    signal示例如下:

    1. #include <stdio.h>  
    2.   
    3. #include <sys/types.h>  
    4.   
    5. #include <stdlib.h>   
    6.   
    7. #include <signal.h>   
    8.   
    9. void func(int sig)   
    10. {  
    11. printf("I get asignal! ");  
    12. }   
    13. int main()   
    14. {    charbuffer[100];   
    15.   
    16.    if(signal(SIGINT, func) == SIG_ERR)  
    17.      {  
    18.      printf("signalerror exit now ");  
    19.      exit(0);  
    20.      }  
    21.      printf("pid:%ld ",(long)getpid());  
    22.   
    23.    for(;;)  
    24.   
    25.      {  
    26.   
    27.      fgets(buffer,sizeof(buffer),stdin);  
    28.   
    29.      printf("bufferis:%s ",buffer);  
    30.   
    31.      }  
    32.  return 0;   
    33. }   

    通常情况下一个用户进程需要处理多个信号。可以在一个程序中注册多个信号处理函数。一个信号可以对应一个处理函数,同时多个信号可以对应一个处理函数。

    对于SIGINT信号 我们可以用ctrl+c或ctrl+z来中断进程,来执行SIGINT注册的函数。

    2、 高级信号处理。

    在linux系统提供了一个功能更强的系统调用。

    1. #include <signal.h>  
    2.   
    3. int sigaction(int signumbet,const structsigaction *act,struct sigaction *oldact)  

     此函数除能注册信号函数外还提供了更加详细的信息,确切了解进程接收到信号,发生的具体细节。

    struct sigaction的定义如下:在linux2.6.39/include/asm-generic/signal.h中实现

    1. struct sigaction  
    2.   
    3. {  
    4.   
    5.      void(*sa_handler)(int);  
    6.   
    7.      void(*sa_sigaction)(int,siginfo_t *,void *);  
    8.   
    9.      sigset_tsa_mask;  
    10.   
    11.      intsa_flags;  
    12.   
    13. }  

    siginfo_t在linux2.6.39/include/asm-generic/siginfo.h中实现:

    sa_flags的取值如下表,取0表示选用所有默认选项。

    SA_NOCLDSTOP:用于表示信号SIGCHLD,当子进程被中断时,不产生此信号,当且仅当子进程结束时产生此信号。

    SA_NOCLDWATI:当信号为SIGCHLD,时可避免子进程僵死。

    SA_NODEFER:当信号处理函数正在进行时,不堵塞对于信号处理函数自身信号功能。

    SA_NOMASK:同SA_NODEFER

    SA_ONESHOT:当用户注册的信号处理函数被执行过一次后,该信号的处理函数被设为系统默认的处理函数。

    SA_RESETHAND:同SA_ONESHOT

    SA_RESTART:是本来不能重新于运行的系统调用自动重新运行。

    SA_SIGINFO:表明信号处理函数是由SA_SIGACTION指定的,而不是由SA_HANDLER指定的,它将显示更多的信号处理函数信息。

    其实sinaction完全可以替换signal函数

    1. #include <stdio.h>   
    2. #include <sys/types.h>   
    3. #include <stdlib.h>    
    4. #include <signal.h>    
    5.   
    6.   
    7. void func(int sig)    
    8.   
    9. {  
    10.   
    11. printf("I get a signal! ");   
    12.   
    13. }    
    14.   
    15. int main()    
    16.   
    17. {   char buffer[100];    
    18.   
    19.     struct sigaction act;  
    20.     act.sa_handler=func;  
    21.     sigemptyset(&act.sa_mask);  
    22.     act.sa_flags = 0;  
    23.   
    24.     if(sigaction(SIGINT,&act, NULL) == -1)  
    25.     {  
    26.     printf("sigaction error exit now ");  
    27.     exit(0);  
    28.     }  
    29.   
    30.     printf("pid:%ld ",(long)getpid());   
    31.   
    32.     for(;;)  
    33.     {  
    34.     fgets(buffer,sizeof(buffer),stdin);  
    35.     printf("buffer is:%s ",buffer);  
    36.     }  
    37.   
    38.     return 0;    
    39.   
    40. }    



  • 相关阅读:
    取多列数据的最大值、最小值sql
    java中实现时间差的计算
    数据更新sql
    自连接的用法sql
    获取第一条,最后一条数据sql
    复制表结构 表数据sql
    用 ORDER BY 生成“排序”列sql
    表之间的数据匹配(生成交叉表)sql
    SIP呼叫流程
    如何在WindowsPhone Bing Map控件中显示必应中国中文地图、谷歌中国中文地图。
  • 原文地址:https://www.cnblogs.com/lidabo/p/4581110.html
Copyright © 2020-2023  润新知