一、信号的概念

  信号(signal)就是告知某个进程发生了某个事件的通知;信号通常是异步发生的,也就是说接受信号的进程不知道信号的准确

  发生时刻;信号可以(1)由一个进程发给另一个进程;(2)由内核发给某个进程

二、信号的处置

  每个信号都有一个与之关联的处置,即收到特定信号时的处理方法;可以通过调用sigaction函数来设定一个信号的处置

  

   (POSIX明确规定了调用sigaction时的语义定义,因此我们自定义signal并调用sigaction,以所期望的POSIX语义提供一个简单的接口)  

  处置方法有三种:

   (1)提供一个函数,只要有特定信号发生它就被调用,这样的函数称为信号处理函数,这种行为称为捕获信号;有两个信号SIGKILL和

     SIGSTOP不能被捕获;信号处理函数由信号值这个单一的整数参数来调用,且没有返回值,其函数原型如下:     

void handler(int signo);

   (2)可以把某个信号的处置方法设定为SIG_IGN来忽略它;SIDKILL和SIDSTOP这两个信号不能被忽略

   (3)可以把某个信号的处置方法设定为SIG_DEF来启用它的默认处置;有个别信号的默认处置为忽略,如SIGCHLD和SIGURG

三、signal函数

#include <signal.h>

typedef void Sigfunc(int);

Sigfunc *signal(int signo, Sigfunc *func) {
    struct sigaction act, oact;

    act.sa_handler = func;  /* 设置处置方法 */
    sigemptyset(&act.sa_mask); /* 把sa_mask置为空集,在信号处理期间不阻塞额外的信号 */
    act.sa_flags = 0;
    if (signo != SIGALRM) { /* 在POSIX兼容的平台上,SIGALRM是在定时器终止时发送给进程的信号 */
      act.sa_flags |= SA_RESTART; 
    }
    if (sigaction(signo, &act, &oact) < 0) {
    return SIG_ERR;
    }
    return (oact.sa_handler);
}

注:a |= b 即 a = a|b,其中|表示位或;a &= b 即 a = a&b,其中&表示位与

四、处理每个信号的选项标志(sa_flags)

五、信号列表

信号      取值          默认动作   含义(发出信号的原因)
SIGHUP      1           Term    终端的挂断或进程死亡
SIGINT      2           Term    来自键盘的中断信号
SIGQUIT     3           Core    来自键盘的离开信号
SIGILL      4           Core    非法指令
SIGABRT     6           Core    来自abort的异常信号
SIGFPE      8           Core    浮点例外
SIGKILL     9           Term    杀死
SIGSEGV     11          Core    段非法错误(内存引用无效)
SIGPIPE     13          Term    管道损坏:向一个没有读进程的管道写数据
SIGALRM     14          Term    来自alarm的计时器到时信号
SIGTERM     15          Term    终止
SIGUSR1     30,10,16    Term    用户自定义信号1
SIGUSR2     31,12,17    Term    用户自定义信号2
SIGCHLD     20,17,18    Ign     子进程停止或终止
SIGCONT     19,18,25    Cont    如果停止,继续执行
SIGSTOP     17,19,23    Stop    非来自终端的停止信号
SIGTSTP     18,20,24    Stop    来自终端的停止信号
SIGTTIN     21,21,26    Stop    后台进程读终端
SIGTTOU     22,22,27    Stop    后台进程写终端
             
SIGBUS      10,7,10     Core    总线错误(内存访问错误)
SIGPOLL                 Term    Pollable事件发生(Sys V),与SIGIO同义
SIGPROF     27,27,29    Term    统计分布图用计时器到时
SIGSYS      12,-,12     Core    非法系统调用(SVr4)
SIGTRAP     5           Core    跟踪/断点自陷
SIGURG      16,23,21    Ign     socket紧急信号(4.2BSD)
SIGVTALRM   26,26,28    Term    虚拟计时器到时(4.2BSD)
SIGXCPU     24,24,30    Core    超过CPU时限(4.2BSD)
SIGXFSZ     25,25,31    Core    超过文件长度限制(4.2BSD)
             
SIGIOT      6           Core    IOT自陷,与SIGABRT同义
SIGEMT      7,-,7       Term
SIGSTKFLT   -,16,-      Term    协处理器堆栈错误(不使用)
SIGIO       23,29,22    Term    描述符上可以进行I/O操作
SIGCLD      -,-,18      Ign     与SIGCHLD同义
SIGPWR      29,30,19    Term    电力故障(System V)
SIGINFO     29,-,-              与SIGPWR同义
SIGLOST     -,-,-       Term    文件锁丢失
SIGWINCH    28,28,20    Ign     窗口大小改变(4.3BSD, Sun)
SIGUNUSED   -,31,-      Term    未使用信号(will be SIGSYS)

 六、POSIX信号语义小结

 (1)一旦安装了信号处理函数,它便一直安装着(较早期的系统是每执行一次就将其拆除);

 (2)在一个信号处理函数运行期间,正被递交的信号是阻塞的;并且,安装处理函数时在递交给sigaction函数的sa_mask信号集中

     指定的任何额外信号也被阻塞;

 (3)如果一个信号在被阻塞期间产生了一次或多次,那么该信号被解阻塞之后通常只递交一次,也就是说Unix信号默认是不排队的;

 (4)利用sigprocmask函数选择性地阻塞或解阻塞一组信号是可能的;这使得我们可以做到在一段临界区代码执行期间,防止捕获某

     些信号,以此保护这段代码