Contents

在Linux中管理流程

1. 概述

在本文中,我们将学习如何在 Linux 系统中查找和操作进程。

2. Linux 系统中的进程

**进程,也称为任务,是程序的执行。**它由需要执行的代码组成,但也包括程序计数器、CPU 寄存器和保存临时数据的堆栈等内容。

此外,它还保存元数据,例如进程的状态、它的标识符和启动它的用户的 id。除了最初的进程外,每个进程都有一个父进程,因此我们可以构建和浏览进程树。

3. 上市流程

让我们从使用*ps *命令列出进程开始。如果没有任何参数,它将在当前 shell 中打印任务及其标识符和命令名称。

要查看所有当前正在运行的进程,我们可以使用*-A选项,而-l*将为我们提供更详细的响应,包括 CPU 使用率和 niceness(稍后 讨论)。我们还可以过滤用户名或 PID 等结果并对输出进行排序。

例如,让我们查找root用户拥有的所有进程,按 CPU 使用率排序:

$ ps -Al -U root --sort=-pcpu
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
1 S  1000  7912  7435 14  80   0 - 324097 futex_ ?       00:01:00 chrome
4 S     0  3585  3449 10  80   0 - 2568814 -    ?        00:00:51 java
4 S  1000  7418  6659  9  80   0 - 381459 poll_s ?       00:00:39 chrome
0 R  1000  6935  6884  4  80   0 - 445515 poll_s ?       00:00:18 gnome-shell
1 S  1000 11058  7435  4  80   0 - 216787 futex_ ?       00:00:03 chrome
0 S  1000  7470  7418  3  80   0 - 182462 poll_s ?       00:00:15 chrome
1 S  1000  7620  7435  2  80   0 - 275830 futex_ ?       00:00:12 chrome
4 R     0  6596  6594  2  80   0 - 68789 -      tty2     00:00:12 Xorg
[...]

请注意,macOS上的 ps 命令在我们可以应用的选项中存在一些差异。

4. 寻找过程

虽然我们可以使用ps和*grep *来查找我们感兴趣的特定进程,但 Linux 为我们提供了一个方便的工具来做到这一点—— pgrep 。例如,我们可以很容易地找到当前 Chrome 进程的 PID:

$ pgrep chrome
621

5. 杀死一个进程

**我们可以通过发送终止信号来终止进程。**Linux 中有很多不同的终止信号,尽管它们中的大多数不是在每个应用程序中都实现的。

每个信号都有一个名称和一个相关的编号,在大多数情况下,我们可以互换使用名称和编号。以下是一些最重要的信号——这些信号被广泛实施并表现出最一致的行为:

  • SIGINT (2) – 与在终端中按Ctrl+C同义,进程可以忽略它
  • SIGQUIT (3) – 类似于 SIGINT,但能够产生核心转储
  • SIGKILL (9) - 强制进程立即终止,不能忽略,并且没有时间优雅地关闭
  • SIGTERM (13) – 让应用程序有时间正常关闭并且可以忽略;行为类似于 SIGINT

*我们可以使用基本的kill 命令杀死一个(或多个)进程。**它接受进程的 PID,并且可以接受终止信号——默认情况下,它使用 SIGTERM。让我们用 SIGKILL 强制终止所有ping*进程:

$ kill -s 9 `pgrep ping`

我们还可以使用方便的*pkill *命令为我们查找 PID:

$ pkill -9 ping

6. 活跃度和权限

就像我们刚刚看到的,我们通常使用信号向相应的进程发送消息。然而,零信号完全打破了这一惯例。它不向指定进程发送任何消息:

kill -0 123

尽管此命令不会向123进程发送任何内容,但它会检查:

  • 指定的进程是存活的
  • 我们有必要的权限向该进程发送任何信号

当进程处于活动状态并且我们确实有权发送信号时,  kill -0以零退出状态静默返回:

$ kill -0 123
$ echo $? # last exit status
0

上面的零返回值意味着我们确实有权向进程123发送信号。

另一方面,如果进程不存在或者我们没有权限向它发出信号,我们将获得一个非零退出状态:

$ kill -0 123
kill: kill 123 failed: no such process
$ each $?
1

**同样,我们可以使用pkill发送相同的信号。**例如,让我们向一个简单的 Netcat 进程发送一个零信号:

$ nc -l localhost 8080 &
$ pkill -0 --newest nc
$ echo $?
0

在这里,我们向与文本“* nc *”匹配的最新进程发送零信号。

7. 规范流程优先级

在 Linux 系统中,进程的优先级由它们的“niceness”决定。好的进程更渴望共享资源,因此它们的优先级较低。同样,不太好的进程不想共享资源,因此它们具有更高的优先级。

默认情况下,每个进程的 niceness 等于 0,范围从 -20 到 19。如果我们想启动一个非默认 niceness 为 15 的进程,我们可以使用*nice *命令:

$ nice -n 15 ping blogdemo.com

如果我们想改变已经运行的进程的友好性,我们可以使用*renice 命令。请注意,在这两种情况下,将 niceness 设置为低于零都需要使用sudo *命令或具有超级用户权限。

8. 使用tophtop监控进程

如果我们想获得更类似于允许我们持续监控进程的 GUI 任务管理器的体验,那么也有终端应用程序。

我们应该看的第一个是*top *。它打印系统资源使用情况的摘要和按 CPU 使用情况排序的实时进程列表。此外,它允许我们向进程发送信号并更改排序参数,尽管界面不是很友好。如果我们不记得某些快捷方式,我们可以随时按“?” 召唤帮助屏幕。

*htop *功能相似,但外观更好,带有着色和垂直滚动。它为我们提供了一个类似于Midnight Commander 的界面,并且应该足够直观,我们无需查看文档即可使用。