UNIX/Linux系统的信号

661阅读 0评论2012-12-27 fellow0305
分类:

信号

信号是软件中断。信号提供了一种处理异步事件的方法,属于异步事件的经典实例。

信号的名字都以SIG三个字符开头,例如SIGABRT是提前退出信号(进程调用abort函数产生),SIGALRM是闹钟信号(由alarm函数设置的计时器超时产生)。而Linux和Solaris都支持应用程序额外定义的信号。

在头文件中,信号都被定义为正整数(即信号编码)。(所以,不存在编号为0的信号。)而kill函数对信号编码0有特殊的应用,POSIX.1将此类信号编码值成为空信号。

UNIX的早期版本提供的信号模型并不可靠;4.3BSD和SVR3对信号模型做了更改,增加了可靠信号机制,但是Berkeley和AT&T所做的更改之间并不兼容。幸运的是,POSIX.1对可靠信号例程进行了标准化。

信号的生命周期

从信号发送到信号处理函数的执行完毕。对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个重要的阶段,这三个阶段由四个重要事件来刻画:信号产生;信号在进程中注册完毕;信号在进程中的注销完毕;信号处理函数执行完毕。相邻两个事件的时间间隔构成信号生命周期的一个阶段。

当一个实时信号发送给一个进程时,不管该信号是否已经在进程中注册,都会被再注册一次,因此,信号不会丢失,因此,实时信号又叫做"可靠信 号"。这意味着同一个实时信号可以在同一个进程的未决信号信息链中占有多个sigqueue结构(进程每收到一个实时信号,都会为它分配一个结构来登记该 信号信息,并把该结构添加在未决信号链尾,即所有诞生的实时信号都会在目标进程中注册);当一个非实时信号发送给一个进程时,如果该信号已经在进程中注 册,则该信号将被丢弃,造成信号丢失。因此,非实时信号又叫做"不可靠信号"。这意味着同一个非实时信号在进程的未决信号信息链中,至多占有一个 sigqueue结构(一个非实时信号产生后,1如果发现相同的信号已经在目标结构中注册,则不再注册,对于进程来说,相当于不知道本次信号发生,信号丢 失;2如果进程的未决信号中没有相同信号,则在进程中注册自己)。

需要注意的要点是:
      1)信号注册与否,与发送信号的函数(如 kill()或 sigqueue()等)以及信号安装函数(signal()及sigaction())无关,只与信号值有关(信号值小于 SIGRTMIN的信号最多只注册一次,信号值在SIGRTMIN及SIGRTMAX之间的信号,只要被进程接收到就被注册)。
      2)在信号被注销 到相应的信号处理函数执行完毕这段时间内,如果进程又收到同一信号多次,则对实时信号来说,每一次都会在进程中注册;而对于非实时信号来说,无论收到多少 次信号,都会视为只收到一个信号,只在进程中注册一次。当然还有有些需要知道的概念比如 低速系统调用,中断系统调用,可重入函数等等概念,请查阅环境高级编程。

信号的分类

信号的分类:

      注:    信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数无关。当然也可以称为实时信号或者非实时信号,非实时信号都不支持排队,都是不可靠信号;实 时信号都支持排队,都是可靠信号。

产生信号的条件

产生信号的条件:

信号处理程序

进程不能简单地测试一个变量来判别是否出现一个信号,而是必须告诉内核“在此信号出现时请执行下列操作”。

具体可以按照三种方式处理,即信号的处理或信号相关的动作:

信号列表

Value Signal Description
1 SIGHUP 终止进程 发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送
2 SIGINT 终止进程 由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
3 SIGQUIT 建立CORE文件 输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程
4 SIGILL 建立CORE文件 非法指令异常
5 SIGTRAP 建立CORE文件 实现相关的硬件异常。一般是 调试异常
6 SIGABRT/SIGIOT 建立CORE文件 实现相关的硬件异常,或者由调用abort函数产生,进程非正常退出
7 SIGBUS 建立CORE文件 某种特定的硬件异常,通常由内存访问引起,包括内存地址对齐出错
8 SIGFPE 建立CORE文件 数学相关的异常,如被0除,浮点溢出,等等
9 SIGKILL 终止进程 立即结束进程的进行,无法阻塞、处理和忽略。
10 SIGUSR1 终止进程 用户自定义signal 1
11 SIGSEGV 建立CORE文件 非法内存访问
12 SIGUSR2 终止进程 用户自定义signal 2
13 SIGPIPE 终止进程 在reader中止之后写Pipe的时候发送
14 SIGALRM 终止进程 用alarm函数设置的 timer超时或setitimer函数设置的interval timer超时
15 SIGTERM 终止进程 请求中止进程,可以被阻塞和处理。Kill命令缺省发送该信号。
16 SIGSTKFLT Linux专用,数学协处 理器的栈异常
17 SIGCHLD 忽略信号 进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略
18 SIGCONT 忽略信号 当stopped的进程恢复运行的时候,自动发送。信号不能被阻塞
19 SIGSTOP 停止进程 暂时停止进程。信号无法阻塞、处理和忽略。
20 SIGTSTP 停止进程 Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程,可以阻塞、处理和忽略
21 SIGTTIN 停止进程 当Background Group的进程尝试读取Terminal的时候发送
22 SIGTTOU 停止进程 当Background Group的进程尝试写Terminal的时候发送
23 SIGURG 忽略信号 当“紧急”或out-of-band的数据被socket接收的时候可能发送
24 SIGXCPU 终止进程 当CPU时间限制超时的时候,可以由getrlimit/setrlimit来读取/改变
25 SIGXFSZ 终止进程 进程超过文件资源大小限制
26 SIGVTALRM 终止进程 虚拟时钟信号,计算的是进程占用CPU的时间。setitimer函数设置的Virtual Interval Timer超时的时候
27 SIGPROF 终止进程 相当于SIGALRM/SIGVTALRM,计算的是进程占用CPU时间和系统调用时间。Setitimer指定的Profiling Interval Timer所产生
28 SIGWINCH 忽略信号 当Terminal的窗口大 小改变的时候,发送给Foreground Group的所有进程
29 SIGIO 忽略信号 异步IO事件,文件描述符准备就绪,可以开始进行输入/输出操作
30 SIGPWR Power Failure,和系统相关。和UPS相关。
31 SIGSYS 非法系统调用
32
33
34 SIGRTMIN
SIGCANCEL 由Solaris Thread Library内部使用,通常不会使用
SIGEMT 和实现相关的硬件异常
SIGFREEZE Solaris专用,Hiberate或者 Suspended时候发送
SIGINFO BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程
SIGLWP 由Solaris Thread Libray内部使用
SIGPOLL 当某个事件发送给Pollable Device的时候发送
SIGTHAW Solaris专用,从Suspend恢复时候发送
SIGWAITING Solaris Thread Library内部实现专用
SIGXRES Solaris专用,进程超 过资源限制的时候发送

signal函数

点击(此处)折叠或打开

  1. #include <signal.h>
  2. void (*signal(int signo, void (*func) (int))) (int);

    其中,signo参数就是UNIX系统的信号名,func的值是常量SIG_IGN(忽略此信号)、常量SIG_DFL(系统默认动作)或信号发生时调用的函数地址。

    返回值:若成功则返回信号以前的处理配置(见下),若出错则返回SIG_ERR。

上一篇:linux平台上GPIO模拟I2C
下一篇:数据结构之图(存储结构、遍历)