进程管理
进程
进程是什么?
进程是正在执行中的程序的一个实例。它是操作系统进行资源分配和调度的基本单位。
程序在启动,运行时(执行命令,运行服务)都会产生进程,需要通过进程 来完成程序的工作。
包含:内存地址空间、安全属性、执行线程、进程状态
程序 vs 进程:
程序是存储在磁盘上的静态指令和数据的集合(一个可执行文件)。当你运行这个程序时,操作系统会将它加载到内存中,并为它分配资源(CPU 时间、内存空间、文件句柄、网络端口等),这时它就变成了一个活跃的、动态的进程。
程序:二进制文件(静态)如
/usr/bin/passwd
进程:程序运行过程(动态),有生命周期及状态
进程来源:
父进程通过
fork 创建子进程
所有进程的祖先进程:
- CentOS5/6: init
- CentOS7/8: systemd
进程状态:
运行状态产生原因:CPU时间片轮转
状态类型:
- R (运行) | S (睡眠) | T (停止)
- Z (僵尸) | X (死亡
生命周期
- 创建 (Created / New): 一个新进程被创建(通常由现有进程通过
fork()系统调用创建)。 - 就绪 (Ready): 进程已准备好运行,所需资源(除 CPU 外)都已获得,等待操作系统调度器分配 CPU 时间片。
- 运行 (Running): 进程正在 CPU 上执行指令。
- 阻塞/等待 (Blocked/Waiting/Sleeping): 进程因等待某个事件(如 I/O 操作完成、信号量可用、子进程终止等)而无法继续执行,主动让出 CPU。
- 终止 (Terminated/Zombie):
- 正常终止: 进程执行完毕或调用
exit()。 - 异常终止: 进程收到无法处理的信号(如
SIGKILL,SIGSEGV)。 - 僵尸状态 (Zombie): 进程已终止,但其退出状态信息(
exit code)还未被父进程读取 (wait()或waitpid())。此时进程占用的系统资源(内存、文件描述符等)已被释放,但在进程表中仍保留一个条目记录其退出状态,等待父进程“收尸”。 - 孤儿进程 (Orphan): 父进程先于子进程终止。Linux 会将孤儿进程的父进程 ID (
PPID) 设置为1(init或systemd进程),由init/systemd负责在其终止后回收资源(防止僵尸进程)。孤儿进程本身是正常运行的。
- 正常终止: 进程执行完毕或调用

进程描述符:
**进程标识符 (pid, ppid, tgid):**唯一且 非负的整数,用于在操作系统中唯一标识一个正在运行的进程。每个进程(包括程序、服务、后台任务 等)启动时都会被分配一个PID,系统通过PID管理和跟踪进程的生命周期。
pid: 进程的唯一 ID。ppid: 父进程 ID。tgid: 线程组 ID (主线程的pid)。对于单线程进程,pid == tgid。
作用
- 唯一标识进程 :在多任务操作系统中,同一时间内系统中可能运行着多个进程。PID 就像每个进程的 “身份证号码”,确保每个进程都有一个独一无二的标识,以便操作系统能够准确地区分和管理这些不同的进程。例如,在 Linux 系统中,可以通过命令
ps -ef查看所有进程及其对应的 PID。 - 进程调度和管理 :操作系统内核利用 PID 对进程进行调度。当系统需要切换进程时,通过 PID 快速找到对应的进程控制块(PCB)等信息,来保存当前进程的运行状态和恢复下一个进程的运行状态。而且在进行进程间通信、资源分配等操作时,PID 也是必不可少的依据。比如,当一个进程需要向另一个进程发送信号时,就需要使用目标进程的 PID 来指定接收信号的进程。
- 方便用户操作 :用户可以通过 PID 来对特定的进程进行操作,如结束进程(通过
kill命令加 PID)、查看进程详细信息等。
PID的特殊角色
- PID=1(Init进程)
- 系统启动后的第一个进程,负责启动和管理其他所有用户进程。
- 如果PID=1的进程终止,系统会触发内核恐慌(Kernel Panic)并崩溃。
- 父进程PID(PPID)
- 每个进程(除Init)都有父进程(Parent Process),父进程的PID称为 PPID。
- 通过ps -ef查看PPID
[root@wickt 桌面]# ps -ef | grep rcu_gp |
进程间通信
进程是独立的,但有时需要协作或交换数据。Linux 提供了多种 IPC 机制:
- 管道 (
|):- 匿名管道:用于具有共同祖先(通常是父子)进程间的通信。数据单向流动(先进先出 FIFO)。通过
pipe()系统调用创建。 - 命名管道 (FIFO):存在于文件系统中(有路径名),可用于任意进程间通信。通过
mkfifo()创建。
- 匿名管道:用于具有共同祖先(通常是父子)进程间的通信。数据单向流动(先进先出 FIFO)。通过
- 信号 (
Signal):- 内核或进程向目标进程发送一个小的、预定义的通知(如
SIGINT(Ctrl+C),SIGKILL,SIGTERM,SIGUSR1)。 - 用于通知进程发生了异步事件(如终止请求、错误)。
kill,pkill命令用于发送信号。
- 内核或进程向目标进程发送一个小的、预定义的通知(如
- 共享内存 (
Shared Memory):- 多个进程可以访问同一块物理内存区域。最快的 IPC 方式。
- 需要配合信号量等机制进行同步,防止竞态条件。
shmget,shmat,shmdt系统调用。
- 消息队列 (
Message Queues):- 在内核中维护的消息链表。进程可以发送格式化的消息到队列,其他进程可以按类型接收。
msgget,msgsnd,msgrcv。
- 在内核中维护的消息链表。进程可以发送格式化的消息到队列,其他进程可以按类型接收。
- 信号量 (
Semaphores):- 主要用于进程/线程间的同步,控制对共享资源的访问(如一次只允许一个进程进入临界区)。
semget,semop。
- 主要用于进程/线程间的同步,控制对共享资源的访问(如一次只允许一个进程进入临界区)。
- 套接字 (
Sockets):- 最强大、最通用的 IPC 机制,可用于不同主机上的进程通信(网络通信),也可用于同一主机上的进程通信(Unix Domain Sockets)。提供可靠的双向字节流或数据报通信。
进程管理
PS查看进程
ps [选项] |
ps auxa: 显示所有用户的进程(不仅仅是当前用户)。u: 以面向用户的格式显示,提供更详细的信息(如用户、CPU、内存等)。x: 显示没有控制终端 (tty) 的进程(如守护进程、后台服务)。- 输出列详解 (典型输出):
USER: 进程所有者(用户)。PID: 进程 ID (唯一标识)。%CPU: 进程使用的 CPU 时间百分比。%MEM: 进程使用的物理内存百分比。VSZ(vsz): 虚拟内存大小 (KiB)。RSS(rss): 驻留集大小,即实际使用的、未被换出的物理内存大小 (KiB)。TTY: 进程关联的终端 (?表示无终端,通常是守护进程)。STAT: 进程状态 (见下文详解)。START: 进程启动时间。TIME: 进程累计使用的 CPU 时间 (分钟:秒)。COMMAND: 启动该进程的命令行(包括参数)。用[]括起来的通常是内核线程。
ps -ef-e: 选择所有进程 (等同于-A)。-f: 显示完整格式的列表。- 输出列详解 (典型输出):
UID: 用户 ID (等同于USER,但显示的是数字 ID)。PID: 进程 ID。PPID: 父进程 ID。C: CPU 利用率 (一个已废弃的字段,通常显示为0或意义不大)。STIME: 进程启动时间 (小时:分钟:秒 或 日期)。TTY: 关联的终端。TIME: 累计 CPU 时间。CMD: 启动该进程的命令名(注意: 默认不显示完整命令行参数!这是与ps aux中COMMAND列的重要区别)。要显示完整命令,通常需要结合-f和-w(或--width) 选项,或者使用ps -efww。
ps -eF-e: 所有进程。-F: 额外的完整格式。比-f提供更多信息列。- 输出列 (在
ps -ef基础上增加):SZ: 内存大小 (页数)。类似于VSZ。RSS: 驻留集大小 (KiB)。PSR: 进程当前运行在哪个 CPU 核心上。ADDR: 内核地址 (意义不大)。WCHAN: 进程在内核中睡眠的函数名。
ps -eH/ps axjf/ps --forest(显示进程树)-H/-f/--forest: 显示进程的层级结构(树状图),清晰展示父子进程关系。-e/ax: 选择所有进程。j: BSD 作业控制格式 (常与f结合显示树状)。- 示例:
ps -ef --forestps auxfps axjf
- 输出特点: 使用缩进或 ASCII 字符绘制树形结构,
CMD列通常只显示命令名而非完整路径。
ps -eLf(查看线程 - LWP)-e: 所有进程。-L: 显示 LWP (Light Weight Process) 和 NLWP (Number of LWPs) 信息。LWP 可以理解为线程。-f: 完整格式。- 关键输出列:
PID: 进程 ID (整个进程)。LWP: 线程 ID (该进程内的轻量级进程 ID)。NLWP: 该进程包含的线程总数。CMD: 命令名 (通常需要结合-w显示完整参数)。
- 用途: 查看多线程应用程序的线程情况。
进程状态 (STAT) 详解:
这是 ps aux 输出中 STAT 列的字母代码组合,表示进程的当前状态:
R(Running/Runnable): 进程正在运行或在运行队列中等待 CPU 调度。S(Interruptible Sleep): 进程在睡眠状态,可被中断。通常是在等待某个事件完成(如 I/O 操作、信号量、用户输入)。D(Uninterruptible Sleep): 进程在睡眠状态,但不可被中断(通常是在等待磁盘 I/O)。这类进程不能被kill信号终止,需要等待 I/O 完成或重启系统。要特别注意这种状态。T(Stopped): 进程被暂停(挂起)。通常由作业控制信号 (SIGSTOP,SIGTSTP) 或调试器暂停。t(Tracing stop): 进程被调试器追踪暂停。Z(Zombie): 僵尸进程。进程已终止,但其退出状态信息尚未被父进程读取 (wait())。它不占用资源(除进程表项外),等待父进程“收尸”。X(Dead): 进程完全死亡(几乎不会在ps输出中看到)。<(High Priority): 进程拥有高优先级(Nice 值 < 0)。N(Low Priority): 进程拥有低优先级(Nice 值 > 0)。s(Session Leader): 进程是一个会话领导者。l(Multi-threaded): 进程是多线程的(有多个 LWP)。+(Foreground Process Group): 进程位于前台进程组。
ps其他常用选项:
-p <PID1>,<PID2>,.../p <PID1> <PID2> ...: 仅显示指定 PID 的进程信息。e.g.,ps -p 1234,5678,ps p 1234 5678.-C <command_name>: 仅显示指定命令名的进程。e.g.,ps -C sshd,ps C sshd.-u <username>/<userid>: 仅显示指定用户拥有的进程。e.g.,ps -u root,ps u apache.--sort <key>: 按指定列排序输出(加-表示降序)。e.g.,ps aux --sort=-%cpu(按 CPU 降序),ps aux --sort=rss(按 RSS 升序). 常用排序键:%cpu,%mem,rss,vsz,pid,start_time。-o <format>/o <format>: 自定义输出格式。这是ps最强大的功能之一。e.g.,ps -eo pid,ppid,user,pcpu,pmem,cmd。可以精确控制显示哪些列及其顺序。使用ps L查看所有可用的格式说明符。-w/w/--width <n>: 强制宽输出模式或指定输出宽度,防止COMMAND或CMD列被截断。e.g.,ps auxww,ps -efw.-M: 在COMMAND列后显示安全上下文(SELinux 相关)。
TOP查看进程
top # 启动 top |

top 界面详解
top 的输出分为两个主要部分:
第一部分:系统汇总信息 (顶部几行)
- 第一行 (
top - ...):top: 命令名。当前时间: 如14:35:07。系统运行时间 (up): 如1:23, 表示系统已运行 1 小时 23 分钟。后面可能跟登录用户数 (1 user)。系统平均负载 (load average): 如0.00, 0.01, 0.05。分别表示过去 1 分钟、5 分钟、15 分钟的平均负载。核心理解:- 对于单核 CPU,
1.00表示 CPU 完全饱和。 - 对于 N 核 CPU,
N.00表示所有核心完全饱和。 - 低于
1.00通常表示 CPU 较空闲;持续高于1.00或远高于核心数表示系统过载。 - 关注 5 分钟和 15 分钟负载更稳定。
- 对于单核 CPU,
- 第二行 (
Tasks: ...): 任务(进程)状态统计。total: 总进程数。running: 处于 运行 (R) 状态的进程数(正在使用 CPU 或等待 CPU 调度)。sleeping: 处于 睡眠 (S) 状态的进程数(等待事件完成,可中断)。stopped: 处于 停止 (T) 状态的进程数(如被Ctrl+Z挂起)。zombie: 僵尸 (Z) 进程数(已终止但父进程未回收)。非零且持续存在需关注。
- 第三行 (
%Cpu(s): ...): CPU 使用率百分比 (关键!)。显示所有 CPU 核心的总体使用情况。us: 用户空间 (user)。普通优先级进程消耗的 CPU 时间。sy: 内核空间 (system)。系统内核进程消耗的 CPU 时间。ni: 用户空间优先级调整 (nice)。低优先级(nice值 > 0)的用户进程消耗的 CPU 时间。id: 空闲 (idle)。CPU 空闲时间百分比。理想情况希望它高。wa: I/O 等待 (IO-wait)。CPU 等待 I/O(磁盘、网络)操作完成的时间百分比。高值通常表示 I/O 瓶颈。hi: 硬件中断 (hardware interrupt)。处理硬件中断消耗的时间。si: 软件中断 (software interrupt)。处理软件中断消耗的时间。st: 虚拟机窃取时间 (steal time)。在虚拟化环境中,被 Hypervisor 偷去服务其他虚拟机的时间。非零表示宿主资源紧张。- (注意:不同版本的
top显示的项目和顺序可能略有差异)
- 第四行 (
KiB Mem : ...): 物理内存 (RAM) 使用情况。total: 总物理内存。free: 完全空闲的内存。操作系统可立即使用的内存。used: 已使用的内存 (total - free - buffers/cache)。注意:Linux 会积极利用内存做缓存,所以used高不一定是坏事。buff/cache: 缓冲区 (buffers) 和缓存 (cache) 使用的内存。buffers: 内核缓冲区,用于块设备 I/O(如磁盘读写)。cache: 页缓存,用于缓存文件数据,加速文件访问。- 这部分内存可以被应用程序快速回收使用。 关注
available更准确。
- 第五行 (
KiB Swap: ...): 交换空间 (Swap) 使用情况。total: 总交换空间大小。free: 空闲的交换空间。used: 已使用的交换空间。avail Mem: (重要!) 可用内存 (Available Memory)。估算的、无需交换即可提供给应用程序使用的内存量。它是free + buff/cache中可回收部分的一个更准确的估计值。这个值比free更能反映系统内存是否充足。avail Mem过低表示内存压力大。
第二部分:进程/任务列表 (下方表格)
默认按 CPU 使用率 (%CPU) 降序排序。每一列代表一个进程的属性:
- PID: 进程 ID (唯一标识)。
- USER: 进程所有者(用户名)。
- PR: 进程的调度优先级 (Priority)。Linux 下是实时优先级。数值越小优先级越高 (RT 任务为负值或很小的正值)。
- NI: Nice 值 (Nice Value)。用户空间优先级调整值。范围
-20(最高优先级) 到19(最低优先级)。普通用户只能增加 Nice 值(降低优先级)。 - VIRT: 虚拟内存大小 (Virtual Memory Size - KiB)。进程使用的虚拟内存总量(代码 + 数据 + 共享库 + 映射但未使用的内存等)。
- RES: 驻留内存大小 (Resident Memory Size - KiB)。进程当前实际使用的、未被换出的物理内存量(包含共享库占用的部分)。这是进程消耗物理内存的关键指标! 与
ps中的RSS对应。 - SHR: 共享内存大小 (Shared Memory - KiB)。
RES中可被其他进程共享的部分(主要是共享库)。 - %CPU: 进程自上次刷新以来使用的 CPU 时间百分比(按单个 CPU 核心计算)。如果进程是多线程的或者系统是多核的,这个值可以超过 100%。例如,一个进程使用了 2 个核心的 100%,那么它的
%CPU会显示200%。 - %MEM: 进程使用的物理内存 (
RES) 占总物理内存的百分比。 - TIME+: 进程自启动以来消耗的总 CPU 时间(格式:分:秒.毫秒)。
+表示显示到毫秒级。 - COMMAND: 启动该进程的命令名或命令行。按
c键可以在命令名和完整命令行之间切换。
常用交互式快捷键 (在 top 运行时按下)
top 的强大之处在于其交互性。以下是最常用和关键的快捷键:
- 排序:
P(大写): 按 %CPU 使用率降序排序 (默认)。M(大写): 按 %MEM 使用率降序排序 (查看内存占用大户)。T(大写): 按 TIME+ (累计 CPU 时间)降序排序。N(大写): 按 PID 降序排序 (新进程在底部)。n(小写): 按 PID 升序排序 (新进程在顶部)。R: 反转当前排序顺序 (升序变降序,降序变升序)。
- 进程管理:
k: 杀死 (kill) 进程。输入k后,会提示输入要杀死的进程的PID,然后提示输入要发送的信号(默认是15SIGTERM,正常终止;输入9发送SIGKILL,强制终止)。按Enter确认。r: 调整进程的 Nice 值 (Renice)。输入r后,提示输入进程PID,然后提示输入新的 Nice 值(-20到19)。需要权限。
- 显示控制:
c: 切换 COMMAND 列显示模式。在只显示命令名和显示完整命令行之间切换。f/F(Fields): 进入字段管理界面 (非常重要!)。可以:- 按
d或空格键 切换 某个字段是否显示 (*表示显示)。 - 按
s键设置某个字段为排序键。 - 按
方向键移动选择字段。 - 按
>或<键移动选中字段的位置 (调整列顺序)。 - 按
q或Esc退出字段管理。
- 按
l(小写 L): 切换顶部第一行 (平均负载) 的显示。t: 切换顶部第二行 (任务状态) 和第三行 (CPU 状态) 的显示模式。可以在文本、条形图、纯文本之间循环切换。m: 切换顶部第四行 (内存) 和第五行 (Swap) 的显示模式。文本和条形图切换。1(数字一): 切换显示所有 CPU 核心的单独统计信息。再按一次切回总体统计。在多核服务器上非常有用。u/U: 按用户筛选进程。输入u后,提示输入用户名,只显示该用户的进程。输入U可以清除筛选。i: 切换显示空闲进程。默认显示所有进程。按i后,只显示非空闲(即%CPU > 0.0)的进程。再按一次恢复。V: 切换到树状视图。以层级结构显示父进程和子进程的关系。再按一次切回列表视图。
- 刷新与退出:
s: 改变刷新间隔 (秒)。输入新的秒数 (如2或0.5)。空格键: 立即刷新一次屏幕。h/?: 显示帮助信息。包含所有可用的快捷键。q: 退出top。
启动选项 (命令行参数)
在启动 top 时可以指定一些选项来改变其初始行为:
-d <秒数>: 设置刷新间隔 (替代交互式s)。如top -d 2(2 秒刷新一次)。-p <PID1>,<PID2>,...: 仅监控指定的进程 ID。如top -p 1234,5678。-u <用户名>: 仅监控指定用户的进程。如top -u apache。-n <次数>: 指定top刷新多少次后自动退出。如top -n 3(刷新 3 次后退出)。-b: 批处理模式 (Batch mode)。将输出重定向到文件或管道时使用,避免控制字符干扰。通常结合-n使用。如top -b -n 1 > top_snapshot.txt。-H: 显示线程 (而不是进程)。在进程列表中,会显示进程内各个线程的信息 (LWP)。结合-p监控特定进程的线程非常有用。如top -H -p <pid>。-o <字段名>: 指定启动时的排序字段 (替代交互式按键)。字段名是大小写敏感的。如top -o %MEM(按内存降序启动),top -o -RES(按 RES 升序启动,注意-表示升序)。
信号控制
kill 命令是 Linux 中用于向进程发送信号的核心工具,它不仅能终止进程,还能实现进程间通信、配置重载等多种功能。
语法
kill [选项] <PID>... # 向指定 PID 发送信号 |
Linux 定义了约 64 种信号(kill -l 查看完整列表),常用信号如下:
| 信号编号 | 信号名 | 说明 | 默认行为 |
|---|---|---|---|
| 1 | SIGHUP |
挂起信号 - 终端断开或控制进程结束 | 终止 |
| 2 | SIGINT |
中断信号 - 用户按下 Ctrl+C |
终止 |
| 3 | SIGQUIT |
退出信号 - 用户按下 Ctrl+\ |
终止 + 生成 core |
| 9 | SIGKILL |
强制终止 - 不可被捕获或忽略,立即结束进程 | 强制终止 |
| 15 | SIGTERM |
终止信号 - 默认信号,请求进程正常退出(清理资源) | 终止 |
| 18 | SIGCONT |
继续执行 - 恢复被 SIGSTOP 暂停的进程 |
继续运行 |
| 19 | SIGSTOP |
暂停信号 - 不可被捕获或忽略,立即暂停进程(Ctrl+Z 发送此信号) |
暂停 |
| 20 | SIGTSTP |
终端暂停 - 用户按下 Ctrl+Z(可被捕获处理) |
暂停 |
SIGTERM (15):优雅终止(进程可捕获此信号进行资源清理)SIGKILL (9):强制杀死(进程无法防御,可能导致资源未释放)SIGSTOP (19)vsSIGTSTP (20):前者不可捕获,后者可被程序处理。
进程优先级
Linux 进程优先级分为两个独立体系:
1. 静态优先级 (Nice 值)
- 范围:
-20(最高)到19(最低) - 默认值:
0 - 特点:
- 用户态进程可调整(普通用户只能降低优先级,即增大 Nice 值)
- 影响 CPU 时间片的分配比例
- 计算公式:
时间片权重 = 1024 / (1.25)^(Nice值)
(Nice=0 时权重为1024,每降低1级权重增加25%)
2. 动态优先级 (实时优先级)
范围:
1(最低)到99(最高)调度策略:
策略 标识符 特点 SCHED_FIFO F先进先出,高优先级进程独占CPU直到退出 SCHED_RR R时间片轮转,同优先级进程轮流执行 SCHED_OTHER TS标准分时调度(使用 Nice 值) SCHED_DEADLINE DL基于截止时间的调度(优先级最高)
虚拟文件系统 proc
/proc/cpuinfo # CPU信息 |
实验:信号控制
首先启动httpd服务
# 由于之前设置了 httpd 服务自启动,这里重启服务 |
查找所有关于httpd的进程
[root@wickt 桌面]# ps -ef | grep httpd |
对http主进程发送信号1
[root@wickt 桌面]# kill -1 3690 # 当服务配置变更以后,可以通过-1来刷新主进程 |
对http主进程发送信号15,查看访问状态
[root@wickt 桌面]# kill -15 3690 |
重启http服务,对http主进程发送信号9杀死进程
[root@wickt 桌面]# systemctl restart httpd |
实验;作业控制
linux可以在一个终端中管理多个任务进程(这些进程称之为job)。 有些进程会占用终端运行很久或是一直占用终端,那么想要运行第二进程就无法操作了, 所以进程可以放到后台执行,这样就不影响在同一个 终端运行第二个进程
# 先查看当前终端运行的 job |
