zoukankan      html  css  js  c++  java
  • linux之C编程学习——信号处理

      信号处理是linux程序的一个特色。用信号处理来模拟操作系统的中断功能。要想使用信号处理功能,你要做的就是填写一个信号处理函数即可。

     1 #include <stdio.h>   
     2 #include <sys/types.h>   
     3 #include <stdlib.h>    
     4 #include <signal.h>    
     5   
     6 int flag = 1;    
     7   
     8 void func(int sig)      
     9 {   
    10     printf("I get a signal!
    ");   
    11     flag = 0;     
    12 }    
    13   
    14 int main()     
    15 {    
    16     signal(SIGINT, func);   
    17     printf("pid:%ld
    ",(long)getpid());   
    18   
    19     while(flag)  
    20     pause();   
    21   
    22     return 0;    
    23 }    

    执行:

    #gcc sig.c -o sig  
      
    #./sig  
      
    在另一终端:   
      
    #kill -INT 333//333是程序打印出的进程号 

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

    1. 注册信号函数

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

      通常情况下一个用户进程需要处理多个信号。可以在一个程序中注册多个信号处理函数。一个信号可以对应一个处理函数,同时多个信号可以对应一个处理函数。对于SIGINT信号 我们可以用ctrl+c或ctrl+z来中断进程,来执行SIGINT注册的函数。

    2. 高级信号处理

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

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

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

    struct sigaction    
    {  
      
         void(*sa_handler)(int);  
      
         void(*sa_sigaction)(int,siginfo_t *,void *);  
      
         sigset_tsa_mask;  
      
         intsa_flags;  
    }  

    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 void func(int sig)     
     7 {    
     8     printf("I get a signal!
    ");    
     9 }    
    10   
    11 int main()    
    12 {   
    13     char buffer[100];    
    14   
    15     struct sigaction act;  
    16     act.sa_handler=func;  
    17     sigemptyset(&act.sa_mask);  
    18     act.sa_flags = 0;  
    19   
    20     if(sigaction(SIGINT,&act, NULL) == -1)  
    21     {  
    22         printf("sigaction error exit now
    ");  
    23         exit(0);  
    24     }  
    25   
    26     printf("pid:%ld
    ",(long)getpid());   
    27   
    28     for(;;)  
    29     {  
    30         fgets(buffer,sizeof(buffer),stdin);  
    31         printf("buffer is:%s
    ",buffer);  
    32     }  
    33   
    34     return 0;    
    35 }

     

  • 相关阅读:
    【C++ Primer Chapter 3 总结】Library vector & string Type
    【C++ Primer Chapter 4 总结】左值 & 右值
    【C++ Primer Chapter 6 总结】函数
    mysql添加索引
    注册plsql
    挑战答题小程序
    开源答题小程序
    答题如何防止作弊
    党史知识答题活动小程序复盘整理
    党史学习教育答题活动复盘
  • 原文地址:https://www.cnblogs.com/geekpaul/p/4294220.html
Copyright © 2011-2022 走看看