linux信号处理

来源:互联网 发布:淘宝怎么咨询人工客服 编辑:程序博客网 时间:2024/06/01 13:52

Linux信号集

1.信号集概念

信号集是一个能表示多个信号的数据类型,sigset_t set ;set即一个信号集。既然是一个集合,就需要对集合进行添加/删除等操作。

int sigemptyset(sigset_t *set); 将set集合置空
int sigfillset(sigset_t *set); 将所有信号加入set集合
int sigaddset(sigset_t *set,int signo); 将signo信号加入到set集合
int sigdelset(sigset_t *set,int signo); 从set集合中移除signo信号
int sigismember(const sigset_t *set,int signo); signo判断信号是否存在于set集合中

代码举例:

view plain
  1. <span style="font-size:16px;color:#000000;">#include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<sys/types.h>  
  4. #include<sys/stat.h>  
  5. #include<signal.h>  
  6.   
  7. int main()  
  8. {  
  9.  sigset_t sigset;  
  10.  sigfillset(&sigset);/*填充所有信号*/  
  11.  if(sigismember(&sigset,SIGINT))/*判断SIGINT*/  
  12.  printf("SIGINT exist in signal_set!\n");  
  13.  if(sigismember(&sigset,SIGTERM))  
  14.   printf("SIGTERM exist in signal_set!\n");  
  15.  if(sigismember(&sigset,SIGABRT))  
  16.   printf("SIGABRT exist in signal_set!\n");  
  17.  if(sigdelset(&sigset,SIGINT)<0)/*移除SIGINT*/  
  18.   perror("del error\n");  
  19.  else  
  20.   printf("SIGINT have been removed!\n");  
  21.  if(sigismember(&sigset,SIGINT))/*再次判断*/  
  22.   printf("SIGINT exist in signal_set!\n");  
  23.  else  
  24.   printf("SIGINT not exist in signal_set!\n");  
  25. }  
  26.   
  27. </span>  

 

输出:

 $ ./sigset
    SIGINT exist in signal_set!
 SIGTERM exist in signal_set!
 SIGABRT exist in signal_set!
 SIGINT have been removed!
 SIGINT not exist in signal_set!

2. 信号集的使用

   定义信号集->设置信号屏蔽位->定义信号处理函数->检测信号
   <1>使用1中的函数即可完成信号集的定义,之后是
   <2>设置信号屏蔽位
   其作用为设置某个进程需要屏蔽的信号

   Int sigprocmask(int how,const sigset_t *set,sigset_t *oset);

  参数

 How 指示如何修改屏蔽信号
 Set是一个非空指针时,根据how修改屏蔽信号
 Oset是一个非空指针时,存放当前屏蔽信号集
 若set为NULL,不改变该进程的信号屏蔽字,how也无意义

 How的取值:

   S I G B L O C K
   该进程新的信号屏蔽字是其当前信号屏蔽字和s e t指向信号集的并集。s e t包含了我们希望阻塞的附加信号

   S I G U N B L O C K
   该进程新的信号屏蔽字是其当前信号屏蔽字和s e t所指向信号集的交集。s e t包含了我们希望解除阻塞的信号

   S I G S E T M A S K
   该进程新的信号屏蔽是s e t指向的值

   举例

view plain
  1. <span style="font-size:16px;color:#000000;">#include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<sys/types.h>  
  4. #include<sys/stat.h>  
  5. #include<signal.h>  
  6.   
  7. /*sigprocmsk的使用*/  
  8.   
  9. void msg(int signo)  
  10. {  
  11.  if(signo==SIGINT)  
  12.   printf("Get SIGINT!\n");  
  13.  else  
  14.   printf("Get SIGQUIT!\n");  
  15. }  
  16.   
  17. int main()  
  18. {  
  19.  sigset_t sigset,oset;/*sigset存放屏蔽信号,oset保存当前屏蔽信号*/  
  20.  sigemptyset(&sigset);/*清空信号集*/  
  21.  sigaddset(&sigset,SIGINT);/*添加SIGINT信号,信号集中仅有SIGINT*/  
  22.  sigprocmask(SIG_BLOCK,&sigset,&oset);/*加入屏蔽信号*/  
  23.   
  24.  signal(SIGINT,msg);  
  25.  signal(SIGQUIT,msg);  
  26.   
  27.  sleep(2);  
  28.   
  29.  raise(SIGINT);/*发送SIGINT信号*/  
  30.  raise(SIGQUIT);   
  31.   
  32.  return 0;  
  33. }   
  34.   
  35. </span>  

  输出

  Get SIGQUIT!

 <3>定义信号处理函数

  s i g a c t i o n函数的功能是检查或修改(或两者)与指定信号相关联的处理动作。此函数取代了U N I X早期版本使用的s i g n a l函数
  Int sigaction(int signo,const struct sigaction *act,struct sigaction *oact);

  参数:signo 要检测或修改动作的信号量
     Act 非空时,表示要修改的动作
     Oact非空时,返回处理该信号的原先动作

     结构体sigaction如下:

      struct sigaction {
      void (*sa_handler)();/*处理函数或SIG_IGN(忽略)或SIG_DFL(默认)*/
       sigset_t sa_mask; /*处理函数过程中被阻塞*/
     int sa_flags; /*标志位,对信号进程处理选项*/
     } ;

  举例

view plain
  1. <span style="font-size:16px;color:#000000;">#include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<sys/types.h>  
  4. #include<sys/stat.h>  
  5. #include<signal.h>  
  6.   
  7. void msg(int signo)  
  8. {  
  9.  if(signo==SIGINT)  
  10.   printf("Get SIGINT!\n");  
  11. }  
  12.   
  13. int main()  
  14. {  
  15.  sigset_t sigset,oset;/*sigset存放屏蔽信号,oset保存当前屏蔽信号*/  
  16.  struct sigaction action1,action2;/*信号处理*/  
  17.   
  18.  action1.sa_handler=msg;  
  19.  sigaction(SIGINT,&action1,&action2);  
  20.   
  21.  sleep(2);  
  22.   
  23.  raise(SIGINT);/*发送SIGINT信号*/  
  24.  return 0;  
  25. }   
  26. </span>  

  输出:

   Get SIGINT

 <4>检测被搁置信号

  Int sigpending(sigset_t *set);
  返回对于调用进程被阻塞不能递送和当前未决的信号集。该信号集通过s e t参数返回。


原文链接:http://linux.chinaitlab.com/command/857706.html

 

附:linux信号

信号是一种进程间通信的方法,它应用于异步事件的处理。信号的实质是一种软中断,它被发送给一个正在被执行的进程以通知进程有某一特定事件发生了。
一、信号含义

 信号拥有自己特定的名字,均以SIG开始,它们在头文件中被定义为一个正整数,这些正整数被称为信号编号(signal number)。
 以下为各个信号的具体含义:

 1.         SIGHUP:当终端发现断线情况时发送给与控制终端相连的控制进程的信号,或控制进程运行结束时发出的信号。它通常用来通知守护进程重新读取系统配置文件。
 2.         SIGINT:进程中断信号,可以用来中断一个正在运行的进程。通常是从终端输入的中断指令,如Ctrl+C键或Delete键。
 3.         SIGQUIT:用于中断前台进程组中的所有进程的信号。由终端输入的退出指令Ctrl+\所产生。这一信号在终端进程的同时,还将产生一个core文件。
 4.         SIGILL:执行非法硬件指令时产生的错误。
 5.         SIGTRAP:跟踪陷阱信号。
 6.         SIGIOT:I/O错误信号。
 7.         SIGBUS:系统总线错误时产生的信号。
 8.         SIGFPE:浮点运算中发生溢出错误时产生的信号。
 9.         SIGKILL:可用于终止任何一个进程的信号,只能由系统管理员发出,是不可捕捉和被忽略的信号之一。
 10.     SIGUSR1:用于用户自定义的预留信号。可由用户在应用程序中自行定义。
 11.     SIGSEGV:使用非法内存地址所产生的信号。
 12.     SIGUSR2:同SIGUSR1。
 13.     SIGPIPE:当对一个读进程已经运行结束的管道执行写操作时产生的信号。
 14.     SIGALRM:由alarm函数设定的时间段终止时,会产生此信号。
 15.     SIGTERM:调用kill(1)命令时缺省产生的信号。
 16.     SIGCHLD:当一个子进程结束或中断时,用于通知其父进程的信号。必要时,父进程可以通过这一信号来了解子进程的状态变化及结束状态等信息。但在大多数情况下,这一信号将被忽略。
 17.     SIGCONT:是使已被中断的进程继续执行的信号。当此信号为某一特定进程产生后,如果此时该进程并没有被中断,将不会有任何操作发生;但如果该进程是一中断了的进程,即使SIGCONT信号被阻塞或被忽略,此进程也将会继续进行。
 18.     SIGSTOP:中断进程的信号。它是一个作业信号,同时也是不可被捕捉和被忽略的信号之一。
 19.     SIGTSTP:交互式的中断信号。通常是在输入中断键Ctrl+Z时,由终端驱动器所产生。
 20.     SIGTTIN:当一个后台进程需要从终端读取数据时,终端驱动器产生的信号。当读取数据的进程忽略或阻塞这个信号,或者读取数据的进程所在的进程组是孤立进程组时,信号不会产生,并且读操作会发生错误返回,将errno置EIO。
 21.     SIGTTOU:当一个后台进程需要向终端写入数据时,终端驱动器产生的信号。当写入数据的进程忽略或阻塞这个信号,或者写数据的进程所在的进程组是孤立进程组时,信号不会产生,并且写操作会发生错误返回,将errno置EIO。与SIGTTIN不同的是,进程可以选择对控制终端进行后台写。如果后台写不被允许则同SIGTTIN信号一样。
 22.     SIGURG:套接字上出现出现紧急情况时产生的信号。
 23.     SIGXCPU:超出CPU时间限制时产生的信号。
 24.     SIGXFSZ:超出文件大小时产生的信号。
 25.     SIGVTALRM:虚拟定时器报警信号。
 26.     SIGPROF:Profiling定时器报警信号。
 27.     SIGWINCH:终端窗口改变时产生的信号。
 28.     SIGIO:表示某个特定文件描述符上可以进行I/O操作的信号。
 29.     SIGPWR:电源失效信号。
 30.     SIGABRT:调用abort函数时产生的信号,将会使进程非正常结束。
 31.     SIGEMT:实现性定义硬件错误发生时产生的信号。

二、信号的处理

 信号是用于处理异步事件的发生的。在一个进程执行过程中,如果有信号被发送到该进程,则该进程将按预先设定好的处理方法进行相应处理。总体上来讲,当信号发生时,进程所采取的处理方法可以分为两种:

 1.         捕捉信号。当某个信号被发送到一个正在运行的进程时,该进程及对此特定信号注册相应的信号处理函数,以完成所需处理。也就是说,在编写程序代码时,对需要进行捕捉处理的信号给出相应的处理程序代码。一旦接收到此信号,则通知系统调用相应信号处理函数做出处理。对应于每一个信号,系统中都有相应的缺省处理函数(通常为终止进程)。可以设定进程在信号发生时使用缺省处理函数进行处理。
 2.         忽略信号。当不希望接收到的信号对进程的执行产生影响,而让进程继续进行时,可以忽略该信号。进程将继续进行而不对信号进行任何处理。


原文链接:http://linux.chinaitlab.com/command/857706.html
原创粉丝点击