FreeBSD 使用手册
上一页 | 第3章 　UNIX 基础 | 下一页

# 3.8 守护进程，信号和杀死进程

当您运行一个编辑器时它是很容易控制的，告诉它去加载文件它就加载。 您之所以能这样做，是因为编辑器提供这样便利去这样做，和因为有编辑器去附上的终端。 一些程序在运行中不需要连续的用户输入，一有机会就从终端里分离到后台去。 例如，一个web系统整天都在作web请求的响应，他不需要您输入任何东西就能完成， 这个类别的另一个例子就是把email的传送。

我们把那些程序叫 守护进程。 守护神是希腊神话中的一些人物，非正非邪，他们是些守护小精灵， 大体上为人类作出贡献。 许多类似web服务或mail服务的系统对于今天仍有用途， 这就是为什么在那么长的时间里，BSD的吉祥物保持为一双鞋加一把钢叉的守护神模样。

守护进程的程序命名通常在最后加一个 “d”。 BIND 是伯克利互联网域名服务 (而实际执行的程序名称则是 `named`)， Apache web系统的程序就叫 `httpd`， 在行式打印机上的打印守护进程就是 `lpd`。 这只是一种惯例，不是标准或硬性规定。 例如，为Sendmail而应用的主要mail守护进程就叫`sendmail`， 却不叫`maild`，这和您推测的一样。

有时可能会需要与守护进程进行通讯。 而 信号 则是其中的一种通讯机制。 可以发送信号给守护进程 (或相关的另一些进程) 来与它进行通信， 不同的信号都有自己的数字编号──其中一些有特殊的含义， 其它的则可以被应用程序自己进行解释， 而一般来说， 应用程序的文档会告诉哪些信号会被如何处理。 您只能给所属于您的进程发信号，假如您给其他人的进程发信号， 进程就会用kill(1) 或 kill(2)权限进行拒绝。 当然,`root` 用户会例外，它能把各种信号发送给每个进程。

在某些情况下，FreeBSD也会向应用软件发送信号。 假如一个应用软件含有恶意写入并试图去访问内存，那是不可想象的，FreeBSD会向那个进程发送 段式违规 信号 (`SIGSEGV`)。 假如一个应用软件使用alarm(3)系统去进行周期性调用闹钟功能，每当达到时间时， FreeBSD会向应用软件发送闹钟信号(`SIGALRM`)。

有两个信号可以停止进程:`SIGTERM` 和 `SIGKILL`。 `SIGTERM`比较友好，进程能捕捉这个信号， 根据您的需要来关闭程序。在关闭程序之前，您可以结束打开的记录文件和完成正在做的任务。 在某些情况下， 假如进程正在进行作业而且不能中断，那么进程可以忽略这个 `SIGTERM`信号。

对于`SIGKILL`信号，进程是不能忽略的。 这是一个 '“我不管您在做什么,立刻停止”'的信号。 假如您发送`SIGKILL`信号给进程， FreeBSD就将进程停止在那里。[1].

您可能会去使用 `SIGHUP`、 `SIGUSR1` 和 `SIGUSR2`信号。 这都是些通用的信号，各种应用程序都可以应用 在各方面的信号发送。

假如您改变了web系统的配置文件──并想web系统去重读它的配置， 您可以停止然后再启动`httpd`。但这样做web系统会导致一个短暂 的中断周期，那样是不受欢迎的。几乎所有的守护进程在编写时，都会指定对`SIGHUP` 信号进行响应从而重读配置文件。 所以， 最好的方法， 就不是杀死并重启 `httpd`， 而是发一个 `SIGHUP` 信号给它。 因为在这方面没有一个标准，不同的守护进程有不同的用法，所以不了解时应读一下守护进程的文档。

发送信号可用kill(1) 命令， 请参考kill(1)所列出的例子。

发送一个信号给进程

这个例子显示了怎样去发一个信号给inetd(8)。 `inetd`配置文件是`/etc/inetd.conf`， 如果想`inetd` 去重读文件系统的话，可以给它发一个`SIGHUP` 信号。

1. 寻找您要发送信号的进程ID，可以用ps(1) 加 grep(1)来完成。 grep(1)命令被用在搜索输出方面，搜索您指定的字符串。 这命令是由普通用户来执行的，而inetd(8)是`root`用户运行的， 所以必须给ps(1)带上`ax`选项。

       % ps -ax | grep inetd
         198  ??  IWs    0:00.00 inetd -wW

   得出 inetd(8) PID号是198。 有时 `grep inetd` 命令也出现在输出中， 这是因为在这方面 ps(1) 也是寻找列表中运行进程。

2. 使用 kill(1) 去发送信号。 因为 inetd(8) 是由 `root`启动的， 您必须使用 su(1) 去 变为 `root` 用户。

       % su
       Password:
       # /bin/kill -s HUP 198

   和大多数 UNIX® 命令一样， kill(1) 如果完成了任务, 就不会给出任何消息。 假如您发送信号给一个不属于您的进程， 您会看到 “`kill: `PID`: Operation not permitted`”. 假如输错了PID号，把信号发送到其他进程，那是坏事。 或者您侥幸，把信号发送到不存在的进程， 您会看见 “`kill: `PID`: No such process`”.

   > 为什么使用 `/bin/kill`?: 许多shell提供了内建 `kill` 命令， 这样， shell就能直接发送信号，而不是运行 `/bin/kill`。 这点非常有用， 但不同shell有不同的语法来指定发送信号的名字， 与其试图把它们学完倒不如简单地直接使用 `/bin/kill `...``。

发送其他的信号也很相似， 只要在命令行替换 `TERM` 或 `KILL` 就行了。

> 重要: 在系统上随意杀死进程是个坏主意，特别是init(8)， 它的进程ID是1，它非常特殊。可以运行 `/bin/kill -s KILL 1` 命令来让系统迅速关机。 当您按下 Return （回车）键之前， 一定要 详细检查您运行 kill(1) 时所指定的参数。

### 备注

[1] | 有点不正确──少数的东西是不能中断的。 例如， 假如进程试图读取网络上另一计算机上的文件， 而那个的计算机会因为某些原因拿走了这个文件， 那这个进程从上述情况来看是 “不能中断”。 最终这个进程会超时，典型的两分钟。一出现超时进程将被杀死。

上一页 | 起始页 | 下一页
进程 | 上一级 | Shells

本文档和其它文档可从这里下载：ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.