3.8.进程和守护进程

FreeBSD 是一个多任务操作系统。在任何时候运行的每个程序都被称为进程。每个正在运行的命令都会启动至少一个新进程,并且 FreeBSD 运行了一些由系统启动的系统进程。

每个进程都通过一个称为进程 ID(PID)的数字唯一标识。与文件类似,每个进程都有一个所有者和组,所有者和组权限用于确定进程可以打开哪些文件和设备。大多数进程通常还有一个启动它们的父进程。例如,shell 是一个进程,shell 中启动的任何命令都是一个具有 shell 作为其父进程的进程。例外情况是一个特殊的进程,称为 init(8),它总是在启动时首先启动的进程,其 PID 始终为 1

有些程序不设计为在持续用户输入的情况下运行,并在第一个机会时与终端断开连接。例如,Web 服务器响应 Web 请求,而不是用户输入。邮件服务器是此类应用程序的另一个示例。这些类型的程序被称为守护进程。术语“守护进程”来自希腊神话,表示一种既不善也不恶,而且隐形执行有用任务的实体。这就是为什么 BSD 吉祥物是一个笑脸的带着球鞋和草叉的守护进程。

有一个约定,即通常将作为守护进程运行的程序命名为带有尾随 "d" 的名字。例如,BIND 是 Berkeley Internet Name Domain,但实际执行的程序是 named。Apache Web 服务器程序是 httpd,线打印机排队守护进程是 lpd。这只是一种命名约定。例如,Sendmail 应用程序的主邮件守护进程是 sendmail,而不是 maild

3.8.1. 查看进程

要查看系统上运行的进程,请使用 ps(1)top(1)。要显示当前正在运行的进程、它们的 PID、它们使用的内存量以及启动它们的命令的静态列表,请使用 ps(1)。要显示所有运行的进程并每隔几秒更新一次显示,以便交互地查看计算机正在执行什么操作,请使用 top(1)

默认情况下,ps(1) 只显示由用户拥有且正在运行的命令。例如:

% ps

输出应类似于以下内容:

 PID TT  STAT    TIME COMMAND
8203  0  Ss   0:00.59 /bin/csh
8895  0  R+   0:00.00 ps

ps(1) 的输出被组织成多个列。PID 列显示进程 ID。PID 从 1 开始分配,最大到 99999,然后再次循环回开始。但是,如果 PID 已经在使用中,它将不会被重新分配。TT 列显示程序正在运行的 tty,STAT 显示程序的状态。TIME 是程序在 CPU 上运行的时间。通常情况下,这不是程序启动后经过的时间,因为大多数程序在需要在 CPU 上花费时间之前会花费大量时间等待事件发生。最后,COMMAND 是用于启动程序的命令。

有许多不同的选项可用于更改显示的信息。其中最有用的一组是 auxww,其中 a 显示所有用户的所有运行进程的信息,u 显示进程所有者的用户名和内存使用情况,x 显示守护进程进程的信息,ww 使 ps(1) 显示每个进程的完整命令行,而不是在屏幕上截断它的长度。

Top(1) 的输出类似于:

% top

输出应类似于以下内容:

last pid:  9609;  load averages:  0.56,  0.45,  0.36              up 0+00:20:03  10:21:46
107 processes: 2 running, 104 sleeping, 1 zombie
CPU:  6.2% user,  0.1% nice,  8.2% system,  0.4% interrupt, 85.1% idle
Mem: 541M Active, 450M Inact, 1333M Wired, 4064K Cache, 1498M Free
ARC: 992M Total, 377M MFU, 589M MRU, 250K Anon, 5280K Header, 21M Other
Swap: 2048M Total, 2048M Free

  PID USERNAME    THR PRI NICE   SIZE    RES STATE   C   TIME   WCPU COMMAND
  557 root          1 -21  r31   136M 42296K select  0   2:20  9.96% Xorg
 8198 dru           2  52    0   449M 82736K select  3   0:08  5.96% kdeinit4
 8311 dru          27  30    0  1150M   187M uwait   1   1:37  0.98% firefox
  431 root          1  20    0 14268K  1728K select  0   0:06  0.98% moused
 9551 dru           1  21    0 16600K  2660K CPU3    3   0:01  0.98% top
 2357 dru           4  37    0   718M   141M select  0   0:21  0.00% kdeinit4
 8705 dru           4  35    0   480M    98M select  2   0:20  0.00% kdeinit4
 8076 dru           6  20    0   552M   113M uwait   0   0:12  0.00% soffice.bin
 2623 root          1  30   10 12088K  1636K select  3   0:09  0.00% powerd
 2338 dru           1  20    0   440M 84532K select  1   0:06  0.00% kwin
 1427 dru           5  22    0   605M 86412K select  1   0:05  0.00% kdeinit4

输出分为两个部分。标题(前五或六行)显示了最后一个运行的进程的 PID,系统负载平均值(这是系统繁忙程度的一种度量),系统正常运行时间(自上次重新启动以来的时间)以及当前时间。标题中的其他数字与正在运行的进程数、已使用的内存和交换空间量以及系统在不同 CPU 状态下花费的时间有关。如果加载了 ZFS 文件系统模块,ARC 行表示从内存缓存中读取的数据量,而不是从磁盘中读取。

在标题下面是一系列列,包含与 ps(1) 输出相似的信息,例如 PID、用户名、CPU 时间量和启动进程的命令。默认情况下,top(1) 还显示进程占用的内存空间量。这分为两列:一个用于总大小,一个用于常驻大小。总大小是应用程序需要的内存量,而常驻大小是实际正在使用的量。

top(1) 每两秒自动更新一次显示。可以使用 -s 指定不同的间隔。

3.8.2. 终止进程

与任何正在运行的进程或守护进程通信的一种方法是使用 kill(1) 发送信号。有许多不同的信号;一些具有特定的含义,而其他信号在应用程序的文档中有描述。用户只能向自己拥有的进程发送信号,向别人的进程发送信号将导致权限被拒绝的错误。例外情况是 root 用户,可以向任何进程发送信号。

操作系统也可以向进程发送信号。如果应用程序编写得很糟糕,并试图访问它不应该访问的内存,FreeBSD 将向该进程发送“段错误”信号(SIGSEGV)。如果应用程序已编写使用 alarm(3) 系统调用在经过一段时间后发出警告的话,它将收到“警告”信号(SIGALRM)。

停止进程可以使用两个信号:SIGTERMSIGKILLSIGTERM 是终止进程的礼貌方式,因为进程可以读取信号,关闭可能已打开的任何日志文件,并在关闭之前尝试完成其正在执行的任务。在某些情况下,如果进程处于无法中断的某个任务中,它可能会忽略 SIGTERM

SIGKILL 不能被进程忽略。向进程发送 SIGKILL 通常会立即停止该进程。[1]

其他常用的信号包括 SIGHUPSIGUSR1SIGUSR2。由于这些是通用信号,不同的应用程序会有不同的响应。

例如,更改 Web 服务器的配置文件后,需要告诉 Web 服务器重新读取其配置。重新启动 httpd 会导致 Web 服务器短暂中断。相反,发送守护进程 SIGHUP 信号。请注意,不同的守护程序将具有不同的行为,因此请参考守护程序的文档,以确定 SIGHUP 是否会实现所需的结果。

重要

随意终止系统上的某个进程是一个糟糕的想法。特别是 init(8),它是 PID 1,也是特殊的。运行 /bin/kill -s KILL 1 是关闭系统的一种快速但不推荐的方式。

最后更新于

FreeBSD 中文社区