zoukankan      html  css  js  c++  java
  • 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. }    



  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/lidabo/p/4581110.html
Copyright © 2011-2022 走看看