3.8.进程和守护进程

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

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

有些程序没有被设计为接受连续的用户输入,并在第一次机会时与终端断开连接。例如,Web 服务器响应 Web 请求,而非用户输入。邮件服务器是这种类型应用程序的另一个示例。这些类型的程序被称为守护进程。守护进程一词来自希腊神话,代表一个非善非恶,并在后台中执行有用任务的存在。这就是为什么 BSD 吉祥物是一个看起来开心的守护进程,并穿着球鞋拿着草叉。

通常有一个惯例,即通常作为守护进程运行的程序的名称以字母"d"结尾。例如,BIND 是伯克利互联网名称域,但实际执行的程序是 named。Apache Web 服务器程序是 httpd,而行打印机排队守护进程是 lpd。这只是一种命名约定。例如,Sendmail 应用程序的主邮件守护进程是 sendmail,而不是 maild。

3.8.1. 查看进程

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

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

输出应类似于以下内容:

 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)的输出类似:

输出应该类似于以下内容:

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 文件系统模块,则会显示一行指示有多少数据是从内存缓存而不是从磁盘读取的。

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

top(1)会自动每两秒更新显示。可以使用不同的间隔进行指定。

3.8.2. 结束进程

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

操作系统也可以向进程发送信号。如果一个应用程序编写不当,并尝试访问不应该访问的内存,FreeBSD 将向进程发送"分段错误"信号( SIGSEGV )。如果一个应用程序已编写使用 alarm(3)系统调用在经过一段时间后警报的,它将被发送"闹钟"信号( SIGALRM )。

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

无法被进程忽略 SIGKILL。向一个进程发送 SIGKILL 通常会立即停止该进程。

其他常用信号是 SIGHUP,SIGUSR1 和 SIGUSR2。由于这些是通用信号,不同的应用程序会有不同的响应。

例如,更改 Web 服务器的配置文件后,需要告知 Web 服务器重新读取其配置。重启 httpd 将导致 Web 服务器出现短暂的停机时间。相反,向守护程序发送 SIGHUP 信号。请注意,不同的守护程序会有不同的行为,因此请参考守护程序的文档,以确定是否 SIGHUP 可以实现期望的结果。

最后更新于

FreeBSD 中文社区 2024