分类: C/C++
2009-06-23 16:53:18
目录
摘要
本章,我们讨论以下话题:
现有的信号
信号的用法
trap 语句的用法
怎么防止用户中断你的程序
你的系统包含了一个列出所有现有信号帮助页面,但是依据你的操作系统,他可能需要用不同的方法打开。在多数linux系统上,将会是 man 7
signal。有任何疑问,使用下面命令来定位准备的帮助页面:
man
-k
signal | grep list
或者
apropos signal | grep
list
信号名可以用 kill -l来查找。
当缺乏陷阱的时候,一个交互式bash脚本忽略 SIGTERM 和 SIGQUIT。 SIGINT 被捕获并处理,在作业控制在激动状态下, SIGTTIN, SIGTTOU 和 SIGTSTP 也是被忽略的。当以命令替代的结果运行的命令也忽略这些信号,当键盘合成的时候。
SIGHUP 默认退出一个shell,一个交互shell将把 SIGHUP 送到所有的作业,运行的或者停止的;如果你想禁用特定进程的默认行为的话,请用 disown 命令察看文档。当接收到收到 SIGHUP 信号时使用内置命令shopt,huponexit选项来杀死所有的作业。
以下信号可以使用Bash shell来发送:
表 12.1. 在Bash中的控制信号
标准组合键 | 意义 |
---|---|
Ctrl+C | 中断信号,向在前台运行的作业发送SIGINT。 |
Ctrl+Y | 延迟悬挂特征,使一个试图从终端读取输入的运行中的进程停止。控制权返回到shell,用户可以从前台,后台或者杀死进程。延迟挂起只有在支持这种特性的操作系统才存在。 |
Ctrl+Z | suspend 信号,向正在运行的程序发送 SIGTSTP,因此停止程序并且把控制权返回给shell。 |
终端设置 | |
---|---|
检查你的 stty 设置,如果你使用 “现代的” 终端模拟,输出的挂起和继续通常是禁用的。标准的 xterm 默认支持 Ctrl+S 和 Ctrl+Q。 |
多数现代的shell,包括Bash,有一个内建的 kill 函数。在Bash里,信号名和数字都可以被接受为选项,选项可以是作业名或者进程号。使用 -l
选项使得一个退出状态可以被报告:0是至少被成功发送的一个信号,有错误发生的话就是非零。
从 /usr/bin
使用 kill 命令,你的系统可能开启了额外选项,比如以不同于你的ID的用户或者执行进程的名字来杀死进程,同使用 pgrep 和 pkill 一样。
Both kill commands send the TERM signal if none is given.
下表所列是最常用的信号:
表 12.2. 常用的kill信号
信号名 | 信号量 | 效果 |
---|---|---|
SIGHUP | 1 | 挂起 |
SIGINT | 2 | 从键盘中断 |
SIGKILL | 9 | 杀死信号 |
SIGTERM | 15 | 中止信号 |
SIGSTOP | 17,19,23 | 停止进程 |
SIGKILL 和 SIGSTOP | |
---|---|
SIGKILL 和 SIGSTOP 可以被捕获,阻止和忽略。 |
当杀死一个或者一系列进程,通常先尝试最小危险的信号 SIGTERM。那样,关心按次序关机的程序得到设计来执行当收到类似清理关闭打开文件的 SIGTERM 信号。如果你向一个进程发送一个 SIGKILL 信号,你就把进程在关闭前进行清理工作的机会给剥夺了,可能造成意想不到的后果。
但是如果一个清理终止没有起作用,那么 INT 或者 KILL 信号可能是唯一的选择。比如,当一个进程不是使用 Ctrl+C中止的话,最好使用kill -9加上进程号。
maud: ~>
ps-ef
| grepstuck_process
maud 5607 2214 0 20:05 pts/5 00:00:02 stuck_processmaud: ~>
kill-9
5607
maud: ~>
ps-ef
| grepstuck_process
maud 5614 2214 0 20:15 pts/5 00:00:00 grep stuck_process
[1]+ Killed stuck_process
当一个进程启动了几个实例, killall 可能更方便。它使用和kill同样的选项,只不过对进程的所有实例起作用。在正式环境使用之前测试这个命令,即便它可能不能像期望的那样在某些商业用途。