Unix/Linux - 进程管理



本章将详细讨论 Unix 中的进程管理。当您在 Unix 系统上执行程序时,系统会为该程序创建一个特殊的环境。此环境包含系统运行程序所需的一切,就好像系统上没有运行其他程序一样。

无论何时您在 Unix 中发出命令,它都会创建或启动一个新进程。当您尝试使用 **ls** 命令列出目录内容时,您就启动了一个进程。简单来说,进程就是正在运行的程序的一个实例。

操作系统通过一个五位数的 ID 号来跟踪进程,这个 ID 号称为 **pid** 或 **进程 ID**。系统中的每个进程都有一个唯一的 **pid**。

由于所有可能的数字都被用完,下一个 pid 会循环或重新开始,因此 pid 最终会重复。在任何时间点,系统中都不存在两个具有相同 pid 的进程,因为 Unix 使用 pid 来跟踪每个进程。

启动进程

启动进程(运行命令)有两种方式:

  • 前台进程
  • 后台进程

前台进程

默认情况下,您启动的每个进程都在前台运行。它从键盘获取输入,并将输出发送到屏幕。

您可以看到 **ls** 命令是如何工作的。如果您想列出当前目录中的所有文件,可以使用以下命令:

$ls ch*.doc

这将显示所有名称以 **ch** 开头并以 **.doc** 结尾的文件:

ch01-1.doc   ch010.doc  ch02.doc    ch03-2.doc 
ch04-1.doc   ch040.doc  ch05.doc    ch06-2.doc
ch01-2.doc   ch02-1.doc

该进程在前台运行,输出定向到我的屏幕,如果 **ls** 命令需要任何输入(它不需要),它会从键盘等待输入。

当程序在前台运行且耗时时,无法运行其他命令(启动任何其他进程),因为在程序完成处理并退出之前,提示符将不可用。

后台进程

后台进程在不连接到键盘的情况下运行。如果后台进程需要任何键盘输入,它会等待。

在后台运行进程的优点是您可以运行其他命令;您不必等到它完成才能启动另一个命令!

启动后台进程最简单的方法是在命令末尾添加一个与号(**&**)。

$ls ch*.doc &

这将显示所有名称以 **ch** 开头并以 **.doc** 结尾的文件:

ch01-1.doc   ch010.doc  ch02.doc    ch03-2.doc 
ch04-1.doc   ch040.doc  ch05.doc    ch06-2.doc
ch01-2.doc   ch02-1.doc

在这里,如果 **ls** 命令需要任何输入(它不需要),它会进入停止状态,直到我们将其移到前台并从键盘提供数据。

第一行包含有关后台进程的信息 - 作业编号和进程 ID。您需要知道作业编号才能在后台和前台之间操作它。

按 Enter 键,您将看到以下内容:

[1]   +   Done                 ls ch*.doc &
$

第一行告诉您 **ls** 命令后台进程已成功完成。第二行是另一个命令的提示符。

列出正在运行的进程

通过运行 **ps**(进程状态)命令,可以轻松查看您自己的进程,如下所示:

$ps
PID       TTY      TIME        CMD
18358     ttyp3    00:00:00    sh
18361     ttyp3    00:01:31    abiword
18789     ttyp3    00:00:00    ps

**ps** 最常用的标志之一是 **-f**(f 代表 full)选项,它提供更多信息,如下例所示:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f

以下是 **ps -f** 命令显示的所有字段的描述:

序号 列 & 描述
1

UID

此进程所属的用户 ID(运行它的人)

2

PID

进程 ID

3

PPID

父进程 ID(启动它的进程的 ID)

4

C

进程的 CPU 利用率

5

STIME

进程启动时间

6

TTY

与进程关联的终端类型

7

TIME

进程占用的 CPU 时间

8

CMD

启动此进程的命令

还可以与 **ps** 命令一起使用其他选项:

序号 选项 & 描述
1

-a

显示所有用户的信息

2

-x

显示没有终端的进程的信息

3

-u

显示更多信息,如 -f 选项

4

-e

显示扩展信息

停止进程

结束进程可以通过几种不同的方式完成。通常,从基于控制台的命令中,发送 CTRL + C 键击(默认中断字符)将退出命令。当进程在前台模式下运行时,这有效。

如果进程在后台运行,则应使用 **ps** 命令获取其作业 ID。之后,您可以使用 **kill** 命令杀死进程,如下所示:

$ps -f
UID      PID  PPID C STIME    TTY   TIME CMD
amrood   6738 3662 0 10:23:03 pts/6 0:00 first_one
amrood   6739 3662 0 10:22:54 pts/6 0:00 second_one
amrood   3662 3657 0 08:10:53 pts/6 0:00 -ksh
amrood   6892 3662 4 10:51:50 pts/6 0:00 ps -f
$kill 6738
Terminated

在这里,**kill** 命令终止 **first_one** 进程。如果进程忽略常规 kill 命令,您可以使用 **kill -9** 后跟进程 ID,如下所示:

$kill -9 6738
Terminated

父进程和子进程

每个 Unix 进程都有两个分配给它的 ID 号:进程 ID (pid) 和父进程 ID (ppid)。系统中的每个用户进程都有一个父进程。

您运行的大多数命令都以 shell 作为其父进程。查看 **ps -f** 示例,其中此命令列出了进程 ID 和父进程 ID。

僵尸进程和孤儿进程

通常,当子进程被杀死时,父进程会通过 **SIGCHLD** 信号更新。然后父进程可以执行其他任务或根据需要重新启动一个新的子进程。但是,有时父进程在其子进程被杀死之前就被杀死了。在这种情况下,“所有进程的父进程”,**init** 进程,成为新的 PPID(父进程 ID)。在某些情况下,这些进程称为孤儿进程。

当进程被杀死时,**ps** 列表可能仍然显示该进程处于 **Z** 状态。这是一个僵尸进程或失效进程。进程已死且未使用。这些进程与孤儿进程不同。它们已完成执行,但仍在进程表中找到条目。

守护进程

守护进程是与系统相关的后台进程,通常以 root 权限运行并响应其他进程的服务请求。

守护进程没有控制终端。它无法打开 ** /dev/tty**。如果您执行 **"ps -ef"** 并查看 **tty** 字段,所有守护进程的 **tty** 都将为 **?**。

准确地说,守护进程是在后台运行的进程,通常等待它能够处理的事情发生。例如,等待打印命令的打印机守护进程。

如果您有一个需要长时间处理的程序,那么将其制作成守护进程并在后台运行它将很有价值。

top 命令

**top** 命令是一个非常有用的工具,可以快速显示按各种标准排序的进程。

它是一个交互式诊断工具,可以频繁更新并显示有关物理和虚拟内存、CPU 使用率、负载平均值和繁忙进程的信息。

以下是运行 top 命令并查看不同进程的 CPU 利用率统计信息的简单语法:

$top

作业 ID 与进程 ID

后台和挂起进程通常通过 **作业编号(作业 ID)** 进行操作。此编号与进程 ID 不同,因为它更短。

此外,作业可以由多个进程组成,这些进程可以串行或并行运行。使用作业 ID 比跟踪单个进程更容易。

广告