第八章、进程管理

进程

进程(Process)是操作系统中正在运行的程序,可以理解成为进行中的程序。

我们安装的程序文件(如:/usr/bin/tar 文件就是 tar 命令对应的程序文件)是计算机 CPU 指令和数据的打包文件。程序文件保存在磁盘上,只占用磁盘空间,并不会占用 CPU、内存等系统资源。当我们运行 tar 命令(如:tar czvf myhome.tar.gz ~/*)时,此时你就开始了 tar 进程。当 tar 命令运行完毕,则此进程结束。

进程是程序的一次执行实例,是操作系统进行资源分配和调度的基本单位。Linux/UNIX 系统中每个进程拥有独立的虚拟地址空间、内存、文件描述符等系统资源,确保程序运行时相互隔离。

本章我们来学习 进程 相关的命令,内容如下:

Ubuntu Linux 操作系统的启动步骤

  1. 当计算机自动是会运行 BIOS/UEFI 中的程序来初始化 CPU(基础运行速度:主频)、内存(真实地址空间)和引导设备(如 U 盘、硬盘)。从固定位置加载自动引导程序(Bootloader)到内存中并开始运行。
  2. Linux 下的 Bootloader 通常使用 GRUB(一个引导程序),在此可以指定你安装的多操作系统(Windows 或 Linux 系统)中的一个,然后根据选择在磁盘上找到操作系统内核程序(Ubuntu Linux 的内核文件保存在 /boot/vmlinuz)加载到内存中并开始运行。
  3. Ubuntu Linux 内核重新初始化CPU,初始化中断向量表、虚拟内存表、磁盘/网络等外设,上述初始化工作完成后,就会挂在根 / 文件系统,然后启动第一个用户级的进程 systemd(位于 /usr/bin/systemd)并开始进程调度。
  4. systemd 完成后续各个用户进程的创建(如:桌面系统进行、账户管理进程等)并等待用户登录进行操作。systemd 不会退出,他一直停留在后台运行,监控所有的子进程运行。

内核程序和用户程序

进程ID(PID)

Linux/UNIX 系统下,每一个用户进程都有一个自己的编号,这个编号唯一的标识了一个正在运行的用户进程,这就是进程ID,也叫做 PID

Linux 下的进程 ID 是从 1 开始的,后面每启用一个进程此数字自动加 1。如果超过了系统能够表达的最大数值则会从 1 开始找到闲置不用的数字给此用户程序赋予此 ID 值。

Ubuntu Linux 系统的 systemd 进程的 ID 永远是 1,这个进程也是系统最重要的一个进程,他相当于所有其他用户进程的 祖进程

父进程ID(PPID)

在 Ubuntu Linux 系统下,除 systemd 由内核创建外,所有其他的进程都是由 systemd 进程直接或间接的创建。这样用户进程的创建就形成一个树形结构。我们把创建此进程的进程称之为父进程,每个进程都会标识一个父进程的ID,即:(PPID)。

systemd 进程没有父进程。

systemd 进程

systemd 进程是现代 Linux 系统中启动的第一个进程,用于进程管理。早期 linux 2.6 内核(及之前版本) 最先启动的进程是 init 进程。 init 进程在单 CPU 时代非常流行,后由 systemd 取代。systemd 的优点是启动速度更快。为了兼容旧的用户程序,现在 Linux 操作系统上的 init 进程实际是 systemd 进程的别名。

1. ps 命令

ps(Process Status)命令用于查看当前 Linux/UNIX 系统的进程状态,他可以显示进程的详细信息。

命令格式

ps [选项]

例如:

weimingze@mzstudio:~$ ps
    PID TTY          TIME CMD
   2429 pts/0    00:00:00 bash
   3704 pts/0    00:00:00 ps
weimingze@mzstudio:~$

ps 命令如果不加任何选项,它会默认显示当前终端(TTY)关联的进程的基本信息(不显示其他用户或后台进程)。

输出的列说明

列名
含义
PID
进程 ID。
TTY
进程关联的终端(如 pts/0 表示当前终端,? 表示无终端)。
TIME
进程累计 CPU 占用时间。
CMD
进程的启动命令。

常用选项

选项
说明
-aux
显示所有进程及资源占用(CPU、内存等)。
-ejH
缩进显示进程树形关系。
--forest
树状结构显示父子进程关系
-e
显示所有进程(包括其他用户)。
-f
完整格式(显示命令行、父进程PPID等)。
-l
长格式显示
-ef
查看所有进程的完整信息(常用)。
-u <用户>
显示指定用户(如:ps -u root)的进程。
-p <进程ID>
显示指定 PID(如:ps -p 1234)的进程。
-C <命令名>
显示指定命令(如:ps -C nginx)的进程。
-t <终端>
显示指定终端(如:ps -t pts/0)的进程。

示例

显示 Linux 操作系统中所有进程及资源占用。

weimingze@mzstudio:~$ ps -aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.3  23348 14224 ?        Ss   12:23   0:05 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    12:23   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        S    12:23   0:00 [pool_workqueue_release]
root           4  0.0  0.0      0     0 ?        I<   12:23   0:00 [kworker/R-rcu_gp]
root           5  0.0  0.0      0     0 ?        I<   12:23   0:00 [kworker/R-sync_wq]
...

各个列说明

列名
含义
USER
启动此进程的用户。
PID
进程 ID。
PPID
父进程 ID。
%CPU
CPU 占用率。
%MEM
内存占用率。
VSZ
虚拟内存大小(KB)。
RSS
实际内存占用(KB)。
TTY
进程关联的终端(如 pts/0 表示当前终端,? 表示无终端)。
STAT
进程状态(如 S=睡眠, R=运行, Z=僵尸)。
START
进程启动时间。
TIME
进程累计 CPU 占用时间。
CMD
进程的启动命令。

进程的状态

在 Linux 内核中,常见有 6 种进程状态,在 进程状态(STAT)这一列的第一个字符标识进程的状态,如下:

状态代码
英文说明
说明
R
(Running)
正在运行状态(在 运行 调度队列中),占用 CPU。
S
(Interruptible Sleeping)
可中断的睡眠(等待事件完成),不占用 CPU。
D
(Uninterruptible Sleep)
不可中断的睡眠(通常与 I/O 相关),不占用 CPU。
Z
(Zombie)
僵尸进程(已终止占用CPU,但占用资源未被父进程回收)。
T
(Stopped)
进程被信号停止(如 Control+Z),不占用 CPU(需要信号恢复运行)。
I
(Idle)
内核线程(某些系统显示为 I)。

示例2

显示进程树形结构。

weimingze@mzstudio:~$ ps -ejH --forest
    PID    PGID     SID TTY          TIME CMD
      2       0       0 ?        00:00:00 kthreadd
      3       0       0 ?        00:00:00  \_ pool_workqueue_release
      4       0       0 ?        00:00:00  \_ kworker/R-rcu_gp
      5       0       0 ?        00:00:00  \_ kworker/R-sync_wq
    ...
   2298    2298    2298 ?        00:00:00 sshd
   2300    2300    2300 ?        00:00:00  \_ sshd
   2426    2300    2300 ?        00:00:00      \_ sshd
   2429    2429    2429 pts/0    00:00:00          \_ bash
   4041    4041    2429 pts/0    00:00:00              \_ ps
   2307    2307    2307 ?        00:00:00 systemd
   2311    2307    2307 ?        00:00:00  \_ (sd-pam)
   2320    2320    2320 ?        00:00:00  \_ pipewire
   2321    2321    2321 ?        00:00:00  \_ pipewire
   2328    2328    2328 ?        00:00:01  \_ snapd-desktop-i
   2488    2328    2328 ?        00:00:00  |   \_ snapd-desktop-i
   2335    2335    2335 ?        00:00:00  \_ wireplumber
   2340    2340    2340 ?        00:00:00  \_ pipewire-pulse
   2360    2360    2360 ?        00:00:00  \_ dbus-daemon
   2430    2430    2430 ?        00:00:00  \_ xdg-document-po
   2452    2452    2452 ?        00:00:00  |   \_ fusermount3
   2437    2437    2437 ?        00:00:00  \_ xdg-permission-
   4022    4022    4022 ?        00:00:00 fwupd

输出的列说明

列名
含义
PID
同上
PGID
进程组 ID(Process Group ID),同一组的进程共享相同的 PGID。
SID
会话 ID(Session ID),关联到终端的进程会话。
TTY
同上
TIME
同上
CMD
同上

练习:

  1. 打开一个 Linux 终端,显示你当前终端内相关的所有进程。
  2. 使用 ps -aux 查看你电脑上的 Linux 下 PID 等于 1 的进程是什么进程。
  3. 使用 ps aux --sort=-%cpu 查看 CPU 使用率最高的前3个进程是什么进程。