linux 信号相关概念

转载 2015年07月09日 20:43:14

信号的阻塞就是让系统暂时保留信号待以后发送。由于另外有办法让系统忽略信号,所以一般情况下信号的阻塞只是暂时的,只是为了防止信号打断敏感的操作。

     

      当需要修改某些全局变量时,可以通过sigprocmask()函数阻塞处理函数中也使用该变量的信号。

      在某些信号处理函数中,为了防止同类信号的到来,可以使用sigaction()函数的sa_mask阻塞特定的信号。

 

阻塞信号的作用

      使用函数sigprocmask()阻塞信号的传递,只是延迟信号的到达。信号会在解除阻塞后继续传递。这种情况往往需要在信号程序和其它程序共享全局变量时,如果全局变量的类型不是sig_atomic_t类型,当一部分程序恰好读、写到变量过程中,产生某个信号,而信号程序里会改变该变量,那么就会产生混乱。为了避免这种混乱,提供程序的可靠性,你必须在操作这类变量前阻塞信号,操作完成后恢复信号的传递。

 

信号集

      所有的信号阻塞函数都使用称作信号集的数据结构来表明受到影响的信号。每一个操作都包括两个阶段:创建信号集,传递信号集给特定的库函数。下面说明信号集和相关的数据类型:
      sigset_t:这个数据类型用来代表信号的集合,有两种方法对它进行初始化。一种是通过函数sigemptyset()使之不包含任何信号,然后用sigaddset()函数加入需要的信号。另一种方法是通过函数sigfillset()使之包含所以信号,然后通过sigdelset()函数删除我们不需要的信号。注意,千万不用试图通过手工方式直接操作这种类型变量,否则会带来严重的错误。下面介绍相关的函数。
      int sigemptyset(sigset_t *set):初始化信号集set使之不包含任何信号,这个函数总是返回0。
      int sigfillset(sigset_t *set):初始化信号集set使之包含所有的信号,这个函数也是总返回0。
      int sigaddset(sigset_t *set, int signum):该函数把信号signum加入到信号集set中,需要注意的是这个函数只是修改了set变量本身,并不作其它操作。该函数成功操作返回0,失败返回-1,错误代码设置成EINVAL,表示signum不是有效的信号代码。
      int sigdelset(sigset_t *set, int signum):该函数从信号集set中删除信号signum,其它方面和sigaddset()函数类似,不再赘述。
      int sigismember(const sigset_t *set,int signum):这个函数测试信号signum是否包含在信号集合set中,如果包含返回1,不包含返回0,出错返回-1。错误代码也只有一个EINVAL,表示signum不是有效的信号代码。

进程的信号掩码

      我们称正在阻塞的信号的集合为信号掩码(signal mask)。每个进程都有自己的信号掩码,创建子进程时子进程将继承父进程的信号掩码。我们可以通过修改当前的信号掩码来改变信号的阻塞情况。
      int sigprocmask(int how, const sigset_t *set,sigset_t *oldset),该函数用来检查和改变调用进程的信号掩码,其中的how参数指出信号掩码改变的方式,必须是下面的值之一:
      SIG_BLOCK,阻塞set中包含的信号。意思是说把set中的信号加到当前的信号掩码中去,新的信号掩码是set和旧信号掩码的并集。
      SIG_UNBLOCK,解除set中信号的阻塞,从当前信号掩码中去除set中的信号。
      SIG_SETMASK,设置信号掩码,既按照set中的信号重新设置信号掩码。

       最后一个参数是进程原来的信号集。如果你只需要改变信号的阻塞情况而不需要关心原来的值,可以传递NULL指针给函数。如果你希望什么也不改变,只是想获得当前信号掩码的信息,那么把set设置成NULL,old中返回当前的设置。
      sigprocmask()函数成功返回0,失败返回-1。失败时错误代码只可能是EINVAL,表示参数how不合法。

      不能阻塞SIGKILL和SIGSTOP等信号,但是当set参数包含这些信号时sigprocmask()不返回错误,只是忽略它们。另外,阻塞SIGFPE这样的信号可能导致不可挽回的结果,因为这些信号是由程序错误产生的,忽略它们只能导致程序无法执行而被终止。
  

举例:禁止关键代码时信号到达

      假定你建立信号SIGALRM的处理函数,在其中设置一个标志。主程序中检查标志并清除,使用函数sigprocmask()控制信号到达:
   #include 
   volatile sig_atomic_t flag=0;
   
   int
   main(void)
   {
       sigset_t block_alarm;
       ... ...
       sigemptyset(&block_alarm);
       sigaddset(&block_alarm,SIGALRM);
       while(1)
       {
           sigprocmask(SIG_BLOCK,&block_alarm,NULL);
           if(flag)
           {
               ... ...
               flag=0;
           }
           sigprocmask(SIG_UNBLOCK,&block_alarm,NULL);
           ... ...
       }
   }

相关文章推荐

linux 信号相关概念

信号的阻塞就是让系统暂时保留信号待以后发送。由于另外有办法让系统忽略信号,所以一般情况下信号的阻塞只是暂时的,只是为了防止信号打断敏感的操作。             当需要修改某些全局变...

信号完整性的相关概念介绍

  • 2011年08月02日 08:41
  • 356KB
  • 下载

信号相关概念

我记得我在进程间通信的时候说到过一种方式——信号量;终止在linux命令行上正在运行的可执行程序所用的ctrl+c,也属于一种信号(是常见SIGINT信号),所以,今天我想具体分享一下与信号相关的一些...

linux的信号的基本概念

信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断。从它的命名可以看出,它的实质和使用很象中断。所以,信号可以说是进程控制的一部分。      进程之间可以互相通过系统调...

Linux入门:信号(一)——基本概念

关于Linux下的信号的基本概念
  • if9600
  • if9600
  • 2017年04月15日 16:02
  • 201

linux信号基本概念和类型

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念。 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断。从它的命名可以看出,它的实质和使用很象中...
  • faihung
  • faihung
  • 2017年03月30日 23:03
  • 148

Linux系统编程(20)——信号基本概念

信号及信号来源信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道...

Linux捕捉信号相关

linux中一共有32种信号,在/usr/include/bits/signum.h 头文件中可以看到 #define    SIGHUP        1    #define    SIGIN...

linux系统编程——信号量相关函数的使用

一、Posix有名信号灯 1.posix有名信号灯函数    函数sem_open创建一个新的有名信号灯或打开一个已存在的有名信号灯。有名信号灯总是既可用于线程间的同步,又能用于进程间的同...

linux作业管理相关信号

SIGHUP:      SIGHUP信号在如下情况下会发生:      1. 控制终端关闭,此时会发送SIGHUP给会发送给session首进程以及几个后台进程组;      2. session首...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux 信号相关概念
举报原因:
原因补充:

(最多只允许输入30个字)