.有多种条件可以产生信号
1)当用户按某些终端键时,产生信号
如在终端按DELETE键通常产生中断信号SIGINT,可以用来中断一个已失去控制程序的方法
2)硬件异常产生信号
除数为0、无效的存储访问等
这些条件通常由硬件检测到,并将其通知内核。然后内核为该条件发生时正在运行的进程产生适当的信号。如对一个无效存储访问的进程产生一个SIGSEGV
3)进程用kill(2)函数可将信号发送给另一个进程或进程组
自然,有些限制: 接收信号进程和发送信号进程的所有者必须相同或发送信号进程的所有者必须是超级用户
4)用户可用kill(1)命令将信号发送给其他进程,此程序是kill函数的界面,常用此命令终止一个失控的后台进程
5)当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号
这里并不是指硬件产生条件(如被0除),而是软件条件。 例如,SIGURG(在网络连接上传来非规定波特率的数据)、SIGPIPE
(在管道的读进程已经终止后一个进程写此管道),以及SIGALRM(进程所设置的闹钟时间已经超时)
信号是异步事件的经典实例。产生信号的事件对进程而言是随机出现的,进程不能只是测试一个变量(如errno)来判别是否发生了一个信号,而是必须告诉内核"在此信号发生时,请执行下列操作"
可要求系统在某个信号出现时按下列三种方式中的一种进行操作
1)忽略此信号
大多数信号都可使用这种方式进行处理,但有两种信号却决不能被忽略。它们是: SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供一种使进程终止或停止的可靠方法。另外,如果忽略某些由硬件异常产生的信号(如非法存储访问或除以0),则进程的行为是未定义的
2)捕捉信号
为了做到这一点要通知内核在某种信号发生时,调用一个用户函数。
在用户函数中,可执行用户希望返回到程序的主循环,终止系统正在为此用户执行的命令。如果捕捉到SIGCHLD信号,则表示子进程已经终止,所以此信号的捕捉函数可以用waitpid以取得此子进程的进程ID以及它的终止状态。
又比如,如果进程创建了临时文件,那么可能要为SIGTERM信号编写一个信号捕捉函数以清除临时文件(kill命令传送的系统默认信号是终止信号)
3)执行系统默认动作. (终止w/core 表示在进程当前工作目录的core文件中复制了此进程的存储图像,多数据UNIX调试程序都使用core文件以检查进程在终止时的状态)
下面列出信号对应的系统默认动作:
SIGABRT 终止w/core 异常终止(调用abort函数时产生,进程异常终止)
SIGALRM 终止 超时(alarm)
SIGBUS 硬件故障 硬件故障
SIGCHLD 忽略 子进程状态改变 (在进程终止或停止时,此信号被送给其父进程)
SIGCONT 继续/忽略 使暂停进程继续
SIGEMT 终止w/core 硬件故障
SIGFPE 终止w/core 算术异常(如除以0,浮点溢出)
SIGHUP 终止 连接断开(如果终端检测到一个连接断开,则此信号送给与终端相关的控制进程)
SIGILL 终止w/core 非法硬件指令
SIGINFO 忽略 键盘状态请求
SIGINT 终止 终端中断符(按DELETE或Ctrl-C)
SIGIO 终止/忽略 异步I/O
SIGIOT 终止w/core 硬件故障
SIGKILL 终止 终止
SIGPIPE 终止 写到无读进程的管道
SIGPOLL 终止 可轮询事件(poll)
SIGPROF 终止 梗概时间超时(setitimer)
SIGPWR 忽略 (UPS上)电源失效/再起动
SIGQUIT 终止w/core 终端退出符(Ctrl-\)
SIGSEGV 终止w/core 无效存储访问
SIGSTOP 暂停进程 停止
SIGSYS 终止w/core 无效系统调用
SIGTERM 终止 终止
SIGTRAP 终止w/core 硬件故障
SIGTSTP 停止进程 终端挂起符
SIGTTIN 停止进程 后台从控制tty读
SIGTTOU 停止进程 后台从控制tty写
SIGURG 忽略 紧急情况
SIGUSR1 终止 用户定义信号
SIGUSR2 终止 用户定义信号
SIGVTALRM 终止 虚拟时间闹钟(setitimer)
SIGWINCH 忽略 终端窗口大小改变
SIGXCPU 终止w/core 超过CPU限制(setrlimit)
SIGXFSZ 终止w/core 超过文件长度限制(setrlimit)