Linux信号机制

软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。内核可以因为内部事件而给进程发送信号,通知进程发生了某个事件。

信号的产生

信号的产生有两个来源:

  • 硬件(特定的输入:ctrl+c,ctrl+\,ctrl+z等,硬件故障等)
  • 软件(系统函数:kill, raise, alarm和setitimer以及sigqueue等)。

标准信号

Linux支持下面列出的标准信号。表格的第二栏指出了指定信号的标准:

P1990表示该信号在原始POSIX.1-1990标准中进行了描述。 P2001表示信号已添加到SUSv2和POSIX.1-2001中。

SignalStandardActionComment
SIGABRTP1990Core来自abort的异常信号
SIGALRMP1990Term来自alarm的计时器到时信号
SIGBUSP2001Core总线错误(内存访问错误)
SIGCHLDP1990Ign子进程停止或终止
SIGCLD-Ign与 SIGCHLD 同义
SIGCONTP1990Cont如果已停止,继续执行
SIGEMT-TermEmulator trap
SIGFPEP1990Core浮点例外
SIGHUPP1990Term终端挂起或者控制进程终止
SIGILLP1990Core非法指令
SIGINFO--与 SIGPWR 同义
SIGINTP1990Term来自键盘的中断信号
SIGIO-TermIO设备就绪 (4.2BSD)
SIGIOT-CoreIOT自陷,与 SIGABRT 同义
SIGKILLP1990Term杀死
SIGLOST-Term文件锁丢失 (unused)
SIGPIPEP1990Term管道损坏:向一个没有读进程的管道写数据
SIGPOLLP2001TermPollable事件发生(Sys V),与 SIGIO 同义
SIGPROFP2001Term分析计时器到时
SIGPWR-Term电力故障 (System V)
SIGQUITP1990Core来自键盘的离开信号
SIGSEGVP1990Core段非法错误(内存引用无效)
SIGSTKFLT-Term协处理器堆栈错误 (unused)
SIGSTOPP1990Stop非来自终端的停止信号
SIGTSTPP1990Stop来自终端的停止信号
SIGSYSP2001Core非法系统调用 (SVr4);
SIGTERMP1990Term终止
SIGTRAPP2001Core跟踪/断点自陷
SIGTTINP1990Stop后台进程读终端
SIGTTOUP1990Stop后台进程写终端
SIGUNUSED-Core未使用信号 与 SIGSYS 同义
SIGURGP2001Ignsocket紧急信号 (4.2BSD)
SIGUSR1P1990Term用户自定义信号1
SIGUSR2P1990Term用户自定义信号2
SIGVTALRMP2001Term虚拟计时器到时 (4.2BSD)
SIGXCPUP2001Core超过CPU时限 (4.2BSD);
SIGXFSZP2001Core超过文件长度限制 (4.2BSD);
SIGWINCH-Ign窗口大小改变 (4.3BSD, Sun)

SIGKILLSIGSTOP信号不能被捕获、阻塞或忽略。

标准信号

下表列出了每个信号的数值。在不同的架构上,许多信号具有不同的数值。

Signalx86 / ARM / most othersAlpha/SPARCMIPSPARISCNotes
SIGHUP1111
SIGINT2222
SIGQUIT3333
SIGILL4444
SIGTRAP5555
SIGABRT6666
SIGIOT6666
SIGBUS7101010
SIGEMT-77-
SIGFPE8888
SIGKILL9999
SIGUSR110301616
SIGSEGV11111111
SIGUSR212311717
SIGPIPE13131313
SIGALRM14141414
SIGTERM15151515
SIGSTKFLT16--7
SIGCHLD17201818
SIGCLD--18-
SIGCONT18192526
SIGSTOP19172324
SIGTSTP20182425
SIGTTIN21212627
SIGTTOU22222728
SIGURG23162129
SIGXCPU24243012
SIGXFSZ25253130
SIGVTALRM26262820
SIGPROF27272921
SIGWINCH28282023
SIGIO29232222
SIGPOLL----Same as SIGIO
SIGPWR3029/-1919
SIGINFO-29/---
SIGLOST--/29--
SIGSYS31121231
SIGUNUSED31--31

实时信号

从2.2版开始,Linux支持最初在POSIX.1b实时扩展中定义的实时信号(现在包括在POSIX.1-2001中)。支持的实时信号范围由宏SIGRTMINSIGRTMAX定义。POSIX.1-2001要求实现至少支持_POSIX_RTSIG_MAX实时信号。

Linux内核支持33种不同的实时信号,范围从32到64。但是glibcPOSIX线程实现在内部使用两个(对于NPTL)或三个(对于LinuxThreads)实时信号。并调整SIGRTMIN的值(34或35)。实时信号的范围在UNIX系统上会有所不同,因此请不要使用硬编码数字来引用实时信号,而应始终使用SIGRTMIN + n表示法来引用实时信号。

与标准信号不同,实时信号没有预定义的含义:所有实时信号都可用于应用程序定义。

Linux信号值

在Linux操作系统中,可以使用kill -l查看支持信号列表。
Linux支持POSIX标准信号 和 POSIX实时信号。

$ kill -l
 1) SIGHUP          2) SIGINT           3) SIGQUIT            4) SIGILL             5) SIGTRAP
 6) SIGABRT         7) SIGBUS           8) SIGFPE             9) SIGKILL           10) SIGUSR1
11) SIGSEGV        12) SIGUSR2         13) SIGPIPE           14) SIGALRM           15) SIGTERM
16) SIGSTKFLT      17) SIGCHLD         18) SIGCONT           19) SIGSTOP           20) SIGTSTP
21) SIGTTIN        22) SIGTTOU         23) SIGURG            24) SIGXCPU           25) SIGXFSZ
26) SIGVTALRM      27) SIGPROF         28) SIGWINCH          29) SIGIO             30) SIGPWR
31) SIGSYS         34) SIGRTMIN        35) SIGRTMIN+1        36) SIGRTMIN+2        37) SIGRTMIN+3
38) SIGRTMIN+4     39) SIGRTMIN+5      40) SIGRTMIN+6        41) SIGRTMIN+7        42) SIGRTMIN+8
43) SIGRTMIN+9     44) SIGRTMIN+10     45) SIGRTMIN+11       46) SIGRTMIN+12       47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15     50) SIGRTMAX-14       51) SIGRTMAX-13       52) SIGRTMAX-12
53) SIGRTMAX-11    54) SIGRTMAX-10     55) SIGRTMAX-9        56) SIGRTMAX-8        57) SIGRTMAX-7
58) SIGRTMAX-6     59) SIGRTMAX-5      60) SIGRTMAX-4        61) SIGRTMAX-3        62) SIGRTMAX-2
63) SIGRTMAX-1     64) SIGRTMAX

信号处理

每个信号都有一个当前处理,即当收到信息时,执行什么处理。上面表格中的Action表示系统 默认的处理行为。

  • Term: 默认操作是终止该过程。
  • Ign:默认操作是忽略信号。
  • Core:默认操作是终止进程并转储核心。
  • Stop:默认操作是停止该过程。
  • Cont:如果当前已停止,则默认操作是继续该过程。

进程可以通过 sigaction 或者 signal 修改信号处理。
信号的处理是每个进程的属性:在多线程应用程序中,信号的处理对于所有线程都是相同的。通过 fork 创建的子进程继承其父进程的信息处理。

参考链接

SIGNAL(7) - Linux Programmer’s Manual