首先,每个信号都有一个名字。名字都以SIG开头。这些名字都由常量正整数定义在<signal.h>头文件中。(实际上一些实现都有自己独立的头文件,但是这些头文件也包含<signal.h>)
没有任何一个信号使用常量0。0是用于kill函数的一个特别案例。POSIX.1叫这个值为空信号(null signal)。
许多条件都能产生信号:
- 当用户按某些终端键时,终端产生信号。如ctrl+C一般来说会产生中断信号(SIGINT)。这可以停止一个无法控制的程序。
- 硬件异常产生信号:如除数为0、无效内存索引,这样类似的情况。这些条件一般是被硬件发现的,然后通知给内核。之后内核会产生一个适当的信号,发送给当前产生异常条件的程序。例如:一个进程执行了无效的内存索引,会产生SIGSEGV信号。
- kill函数允许一个进程发送任何信号到另一个进程或进程组中。正常情况下有个限制:我们必须是接收信号的进程所有者,或者我们必须是超级用户。
- kill命令允许我们发送信号到另一个进程。这个程序刚好有kill函数的接口。这个命令常用于制止一个无法停止的后台进程。
- 当某件事发生,这件事应该通知给某进程时,软件条件也能产生信号。这不是硬件产生条件(如除数为0这样的条件),而是软件条件。例如:SIGURG(当超出带宽的数据到来的时候产生),SIGPIPE(当读取PIPE的程序已经终止,进程仍然写PIPE时产生。),SIGALRM(当进程设置的始终到期时产生)
信号是异步事件的典型例子。信号可以发生在进程运行的任意时间里。进程不能简单的测试某一变量值来判断信号是否产生了。而是进程必须告诉内核“如果某一信号发生了,那么就这么干。”
我们可以让内核做下面三件事之一。我们称之为“信号处置(disposition of the signal)”或“信号关联动作”。
- 忽略信号。这用于多数信号,但是两种信号不能忽略:SIGKILL和SIGSTOP。原因是这两种信号不能被忽略,这是给内核或超级用户提供一种可靠的结束进程的方法。如果忽略了由硬件产生的异常,那么进程的行为是未定义的。
- 捕获信号。这么做是告诉内核,无论可时产生了信号,就调用我们的某一程序进程处理。在我们的函数中,我们可以做任何我们想处理的条件。如果我们写了一个命令中断,当用户使用键盘产生一个中断信号时,我们可能想返回主函数,终止用户已经执行的任何命令。如果SIGCHLD信号被捕获,它意味着子进程已经终止,所以信号捕获函数可以调用waitpid去获得子进程的PID和终止状态。做为另一个例子,如果进程已经创建了临时文件,我们可能想写一个捕获SIGTERM(终止信号是kill命令默认发送的信号)信号的函数,去清除临时文件。注意:SIGKILL和SIGSTOP这两个信号不能被捕获。
- 使用默认动作。每个信号都有一个默认动作。注意:对于多数信号来说默认动作是结束进程。
下面表格显示了信号的默认动作:
Figure 10.1. UNIX System signals
Name
|
Description
|
ISO C
|
SUS
|
FreeBSD 5.2.1
|
Linux 2.4.22
|
Mac OS X 10.3
|
Solaris 9
|
Default action
|
SIGABRT
|
abnormal termination (abort)
|
•
|
•
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGALRM
|
timer expired (alarm)
|
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGBUS
|
hardware fault
|
|
•
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGCANCEL
|
threads library internal use
|
|
|
|
|
|
•
|
ignore
|
SIGCHLD
|
change in status of child
|
|
•
|
•
|
•
|
•
|
•
|
ignore
|
SIGCONT
|
continue stopped process
|
|
•
|
•
|
•
|
•
|
•
|
continue/ignore
|
SIGEMT
|
hardware fault
|
|
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGFPE
|
arithmetic exception
|
•
|
•
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGFREEZE
|
checkpoint freeze
|
|
|
|
|
|
•
|
ignore
|
SIGHUP
|
hangup
|
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGILL
|
illegal instruction
|
•
|
•
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGINFO
|
status request from keyboard
|
|
|
•
|
|
•
|
|
ignore
|
SIGINT
|
terminal interrupt character
|
•
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGIO
|
asynchronous I/O
|
|
|
•
|
•
|
•
|
•
|
terminate/ignore
|
SIGIOT
|
hardware fault
|
|
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGKILL
|
termination
|
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGLWP
|
threads library internal use
|
|
|
|
|
|
•
|
ignore
|
SIGPIPE
|
write to pipe with no readers
|
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGPOLL
|
pollable event (poll)
|
|
XSI
|
|
•
|
|
•
|
terminate
|
SIGPROF
|
profiling time alarm (setitimer)
|
|
XSI
|
•
|
•
|
•
|
•
|
terminate
|
SIGPWR
|
power fail/restart
|
|
|
|
•
|
|
•
|
terminate/ignore
|
SIGQUIT
|
terminal quit character
|
|
•
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGSEGV
|
invalid memory reference
|
•
|
•
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGSTKFLT
|
coprocessor stack fault
|
|
|
|
•
|
|
|
terminate
|
SIGSTOP
|
stop
|
|
•
|
•
|
•
|
•
|
•
|
stop process
|
SIGSYS
|
invalid system call
|
|
XSI
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGTERM
|
termination
|
•
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGTHAW
|
checkpoint thaw
|
|
|
|
|
|
•
|
ignore
|
SIGTRAP
|
hardware fault
|
|
XSI
|
•
|
•
|
•
|
•
|
terminate+core
|
SIGTSTP
|
terminal stop character
|
|
•
|
•
|
•
|
•
|
•
|
stop process
|
SIGTTIN
|
background read from control tty
|
|
•
|
•
|
•
|
•
|
•
|
stop process
|
SIGTTOU
|
background write to control tty
|
|
•
|
•
|
•
|
•
|
•
|
stop process
|
SIGURG
|
urgent condition (sockets)
|
|
•
|
•
|
•
|
•
|
•
|
ignore
|
SIGUSR1
|
user-defined signal
|
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGUSR2
|
user-defined signal
|
|
•
|
•
|
•
|
•
|
•
|
terminate
|
SIGVTALRM
|
virtual time alarm (setitimer)
|
|
XSI
|
•
|
•
|
•
|
•
|
terminate
|
SIGWAITING
|
threads library internal use
|
|
|
|
|
|
•
|
ignore
|
SIGWINCH
|
terminal window size change
|
|
|
•
|
•
|
•
|
•
|
ignore
|
SIGXCPU
|
CPU limit exceeded (setrlimit)
|
|
XSI
|
•
|
•
|
•
|
•
|
terminate+core/ignore
|
SIGXFSZ
|
file size limit exceeded (setrlimit)
|
|
XSI
|
•
|
•
|
•
|
•
|
terminate+core/ignore
|
SIGXRES
|
resource control exceeded
|
|
|
|
|
|
•
|
ignore
|
|
SUS列上的•代表它是作为POSIX.1的一部分定义的。XSI代表它是以XSI扩展为基础的。
默认动作为“terminate+core”,它意味着进程的内存镜像已经离开该进程工作目录的core文件。(因为文件被命名为core,它显示了这个功能已经做为UNIX 系统的一部分多长时间了。)这个文件能用于UNIX系统的调式工作,去检查进程结束时的状态。
PS:core文件是发行版本的功能。虽然不是POSIX.1的功能,但是它已经是Single UNIX Specification 的XSI扩展中移植实现指定的功能。
以下几种情况core文件不会产生:
- 进程使用了set-user-ID并且当前用户不是程序文件的所有者。
- 进程使用了set-group-ID并且当前用户不是程序文件的组所有者。
- 用户没有写当前工作目录的权限。
- core file已经存在,并且用户没有权限写这个文件。
- 文件太大(查看RLIMIT_CORE的设置)
假设core文件不存在,它的权限通常是用户读、写。
具体每个信号的描述详见APUE第10.2节