在 Linux 中,每个程序和守护进程都是一个“进程”。大多数进程代表一个正在运行的程序。其他程序可以派生出其他进程,例如监听特定事件发生并对其做出响应的进程。并且每个进程都需要一定量的内存和处理能力。运行的进程越多,需要的内存和 CPU 周期就越多。在较旧的系统上,例如我七年前的笔记本电脑,或较小的计算机,例如 Raspberry Pi,如果你密切关注后台运行的进程,就可以最大限度地利用你的系统。
你可以使用 ps 命令获取正在运行的进程列表。你通常需要给 ps 一些选项,以便在其输出中显示更多信息。我喜欢使用 -e 选项来查看系统上运行的每个进程,以及 -f 选项来获取有关每个进程的完整详细信息。以下是一些示例
$ ps
PID TTY TIME CMD
88000 pts/0 00:00:00 bash
88052 pts/0 00:00:00 ps
88053 pts/0 00:00:00 head
$ ps -e | head
PID TTY TIME CMD
1 ? 00:00:50 systemd
2 ? 00:00:00 kthreadd
3 ? 00:00:00 rcu_gp
4 ? 00:00:00 rcu_par_gp
6 ? 00:00:02 kworker/0:0H-events_highpri
9 ? 00:00:00 mm_percpu_wq
10 ? 00:00:01 ksoftirqd/0
11 ? 00:00:12 rcu_sched
12 ? 00:00:00 migration/0
$ ps -ef | head
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 13:51 ? 00:00:50 /usr/lib/systemd/systemd --switched-root --system --deserialize 36
root 2 0 0 13:51 ? 00:00:00 [kthreadd]
root 3 2 0 13:51 ? 00:00:00 [rcu_gp]
root 4 2 0 13:51 ? 00:00:00 [rcu_par_gp]
root 6 2 0 13:51 ? 00:00:02 [kworker/0:0H-kblockd]
root 9 2 0 13:51 ? 00:00:00 [mm_percpu_wq]
root 10 2 0 13:51 ? 00:00:01 [ksoftirqd/0]
root 11 2 0 13:51 ? 00:00:12 [rcu_sched]
root 12 2 0 13:51 ? 00:00:00 [migration/0]
最后一个示例显示了最详细的信息。在每一行中,UID(用户 ID)显示了拥有该进程的用户。PID(进程 ID)代表每个进程的数字 ID,而 PPID(父进程 ID)显示了派生此进程的进程的 ID。在任何 Unix 系统中,进程都从 PID 1 开始计数,PID 1 是内核启动后运行的第一个进程。在这里,systemd 是第一个进程,它派生了 kthreadd。而 kthreadd 创建了其他进程,包括 rcu_gp、rcu_par_gp 和许多其他进程。
使用 kill 命令管理进程
系统会自行处理大多数后台进程,因此你无需担心它们。你只需要参与管理你创建的任何进程,通常是通过运行应用程序。虽然许多应用程序一次运行一个进程(想想你的音乐播放器或终端模拟器或游戏),但其他应用程序可能会创建后台进程。其中一些进程在你退出应用程序后可能会继续运行,以便在你下次启动应用程序时它们可以快速恢复工作。
当我运行 Chromium 时,进程管理就成了一个问题,Chromium 是 Google Chrome 浏览器的开源基础。Chromium 使我的笔记本电脑运行得非常吃力,并启动了许多额外的进程。现在,我可以看到这些 Chromium 进程正在运行,而我只打开了五个标签页
$ ps -ef | fgrep chromium
jhall 66221 [...] /usr/lib64/chromium-browser/chromium-browser [...]
jhall 66230 [...] /usr/lib64/chromium-browser/chromium-browser [...]
[...]
jhall 66861 [...] /usr/lib64/chromium-browser/chromium-browser [...]
jhall 67329 65132 0 15:45 pts/0 00:00:00 grep -F chromium
我省略了一些行,但有 20 个 Chromium 进程和一个 grep 进程正在搜索字符串“chromium”。
$ ps -ef | fgrep chromium | wc -l
21
但是,在我退出 Chromium 后,这些进程仍然保持打开状态。你如何关闭它们并回收这些进程占用的内存和 CPU 呢?
kill 命令允许你终止进程。在最简单的情况下,你告诉 kill 你要停止的进程的 PID。例如,要终止这些进程中的每一个,我需要对 20 个 Chromium 进程 ID 中的每一个执行 kill 命令。一种方法是使用一个命令行获取 Chromium PID,另一个命令行对该列表运行 kill
$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}'
66221
66230
66239
66257
66262
66283
66284
66285
66324
66337
66360
66370
66386
66402
66503
66539
66595
66734
66848
66861
69702
$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}' > /tmp/pids
$ kill $( cat /tmp/pids)
最后两行是关键。第一个命令行生成 Chromium 浏览器的进程 ID 列表。第二个命令行对该进程 ID 列表运行 kill 命令。
介绍 killall 命令
一次停止大量进程的更简单方法是使用 killall 命令。正如你可能从名称中猜到的那样,killall 终止所有与名称匹配的进程。这意味着我们可以使用此命令停止所有失控的 Chromium 进程。这就像这样简单
$ killall /usr/lib64/chromium-browser/chromium-browser
但要小心使用 killall。此命令可以终止任何与你提供的名称匹配的进程。这就是为什么我喜欢首先使用 ps -ef 检查我的运行进程,然后针对我要停止的命令的确切路径运行 killall。
你可能还想使用 -i 或 --interactive 选项,以便在 killall 停止每个进程之前提示你。
killall 还支持使用 -o 或 --older-than 选项选择早于特定时间的进程。如果你发现一组已经无人值守运行了数天的失控进程,这将非常有用。或者你可以选择比特定时间更晚的进程,例如你最近启动的失控进程。使用 -y 或 --younger-than 选项选择这些进程。
管理进程的其他方法
进程管理可能是系统维护的重要组成部分。在我早期的 Unix 和 Linux 系统管理员职业生涯中,终止失控作业的能力是保持系统正常运行的有用工具。在现代 Linux 桌面中,你可能不需要终止失控进程,但是了解 kill 和 killall 可以在事情最终出错时帮助你。
你还可以寻找其他管理进程的方法。就我而言,在我退出浏览器后,我实际上不需要使用 kill 或 killall 来停止后台 Chromium 进程。Chromium 中有一个简单的设置可以控制这一点

尽管如此,密切关注系统上正在运行的进程并在需要时知道如何管理它们始终是一个好主意。
7 条评论