Linux 进程管理

Administrator 4

Linux 进程管理


目录

  1. 进程与线程的基本概念
  2. 进程查看:ps / top / htop
  3. 进程状态:R / S / D / Z / T
  4. 看懂 top 输出
  5. 结束进程:kill / pkill 与信号
  6. 前台 / 后台作业控制
  7. systemd 入门:systemctl 与开机自启
  8. 进程优先级:nice / renice
  9. 僵尸进程与孤儿进程
  10. 总结与练习

一、进程与线程的基本概念

进程(Process) 是正在运行的程序的一个实例,是系统分配资源的基本单位。程序是静态的文件,进程是动态的运行实体。

关键概念

  • PID(Process ID):进程的唯一编号。
  • PPID(Parent PID):父进程的 PID。每个进程都由另一个进程(父进程)创建。
  • 进程与线程:一个进程可以包含多个线程(Thread),线程是进程内并行执行的最小单位。

查看当前 shell 的进程信息:

echo $$              # 当前 shell 的 PID
echo $PPID           # 当前 shell 的父进程 PID
pstree               # 以树形显示进程父子关系
pstree -p            # 同时显示 PID

进程树:所有进程的最顶层是 PID 为 1 的进程(Rocky/RHEL 上通常是 systemd),它负责管理整个系统。

参考:man 7 process菜鸟教程 - Linux 进程管理


二、进程查看:ps / top / htop

2.1 ps —— 快照查看进程

ps(process status)显示某个时刻的进程快照。常用组合:

ps               # 只显示当前终端自己的进程
ps -ef           # ★显示所有进程(-e all,-f 完整格式)
ps aux           # ★另一种常用写法(a 所有终端,u 用户格式,x 无终端进程)
ps -ef | grep nginx   # 配合 grep 查找指定进程
ps -fp <pid>     # 查看指定 PID 的进程
ps -u username   # 查看某用户的进程

ps aux 的输出列:

含义
USER 运行该进程的用户
PID 进程号
%CPU CPU 占用率
%MEM 内存占用率
VSZ 虚拟内存大小(KB)
RSS 实际常驻内存大小(KB)
TTY 关联的终端(? 表示无终端/后台)
STAT 进程状态(见第三章)
START 启动时间
TIME 累计占用 CPU 时间
COMMAND 启动命令

2.2 top —— 实时动态查看

top 实时刷新显示进程和系统资源,是监控 CPU/内存的主力工具。

top                 # 进入实时监控界面
top -d 2            # 每 2 秒刷新一次
top -p <pid>        # 只监控指定进程
top -u username     # 只看某用户进程

进入 top 后的常用按键:

按键 作用
q 退出
P 按 CPU 占用排序(默认)
M 按内存占用排序
k 杀掉某个进程(会提示输入 PID)
r 调整某个进程的优先级(renice)
1 展开/折叠多核 CPU 显示
h 帮助

详细解析见第四章。

2.3 htop —— 更友好的进程查看

htop 是 top 的增强版,带彩色界面、可鼠标操作,需单独安装:

sudo dnf install -y htop    # Rocky 安装
htop
  • 彩色显示、上下左右/鼠标可操作。
  • 直接按 F9 杀进程、F6 排序、F7/F8 调整优先级,更直观。
  • Ubuntu/Debian 用 sudo apt install htop

参考:man 1 psman 1 topman 1 htop


三、进程状态:R / S / D / Z / T

ps 的 STAT 列和 top 的 S 列会显示进程状态,常见如下:

状态 名称 含义
R Running 正在运行或处于可运行队列
S Sleeping(可中断) 正在睡眠/等待,可被信号唤醒(最常见)
D Uninterruptible sleep 不可中断睡眠(通常在等待磁盘 I/O),不能用 kill 杀掉
Z Zombie 僵尸进程(进程已结束但未被父进程回收)
T Stopped 已停止/挂起(如被 Ctrl+Z 或 SIGSTOP 挂起)
I Idle 空闲的内核线程(新内核有)

STAT 列还可能带附加符号

符号 含义
+ 在前台进程组中
< 高优先级
N 低优先级
s 会话领导者(session leader)
l 多线程进程

示例S+ 表示"可中断睡眠 + 前台";Z 表示僵尸进程。

僵尸进程(Z) 会在第九章详细讲解。

参考:man 1 ps(STATE 部分)、man ps 中的 PROCESS STATE CODES


四、看懂 top 输出

top 界面上半部分是系统总览,下半部分是进程列表

4.1 第一行:系统运行时间与负载

top - 10:20:30 up 3 days, 2:15,  3 users,  load average: 0.30, 0.45, 0.52
  • 10:20:30:当前时间。
  • up 3 days, 2:15:系统已运行 3 天 2 小时 15 分。
  • 3 users:当前登录用户数。
  • load average: 0.30, 0.45, 0.52系统负载(过去 1 分钟、5 分钟、15 分钟的平均运行队列长度)。

负载怎么看:负载值约等于"在排队等待 CPU 的进程数"。通常负载 < CPU 核数表示正常,远大于核数表示 CPU 过载。例如 4 核机器负载接近 4 或以上需关注。

4.2 第二行:进程与线程数

Tasks: 220 total,   2 running, 218 sleeping,   0 stopped,   0 zombie
  • total:总进程数;running:运行中;sleeping:睡眠中;stopped:已停止;zombie:僵尸进程。

注意 zombie 这一项:若持续有僵尸进程且数量增长,需排查(见第九章)。

4.3 第三、四行:CPU 与内存使用

%Cpu(s): 10.0 us,  5.0 sy,  0.0 ni, 85.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   7840.0 total,  3000.0 free,  3200.0 used,  1640.0 buff/cache
MiB Swap:   2048.0 total,  2048.0 free,     0.0 used,  3000.0 avail Mem

CPU 各项(us/sy/ni/id/wa/hi/si/st)

含义
us 用户态 CPU 时间占比
sy 系统态(内核)CPU 时间占比
ni 被 nice 调整过优先级的进程占用的 CPU
id 空闲 CPU 占比(越大越空闲
wa 等待 I/O 的 CPU 占比(过高说明磁盘/IO 慢
hi / si 硬件 / 软件中断
st 被虚拟化超卖偷走的 CPU(虚拟机)

内存(Mem/Swap):total 总量、free 空闲、used 已用、buff/cache 缓存、avail Mem 可用内存。

注意:Linux 会把空闲内存用作缓存(buff/cache),所以"used"看着高不代表内存不足,要看 avail Mem(真正可用)。

4.4 进程列表各列

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1234 root      20   0  162152   7500   5680 S   1.3   0.1   0:01.25 httpd
含义
PID 进程号
USER 用户
PR 内核调度优先级(nice 值映射,20=普通)
NI nice 值(-20~19,越低越优先)
VIRT 虚拟内存大小
RES 实际物理内存
SHR 共享内存
S 状态(见第三章)
%CPU CPU 占用率
%MEM 内存占用率
TIME+ 累计 CPU 时间
COMMAND 命令

参考:man 1 top菜鸟教程 - Linux top 命令


五、结束进程:kill / pkill 与信号

5.1 信号(Signal)是什么

信号是系统向进程发送的异步通知,用于让进程做出某种响应(如退出)。进程管理中的"杀进程"本质就是发送信号

查看所有信号:kill -l

5.2 常用信号

信号 编号 含义 默认行为
SIGTERM 15 终止信号(默认) 让进程优雅退出,进程可捕获处理
SIGKILL 9 强制终止 立即杀死,进程无法捕获/忽略
SIGINT 2 中断(Ctrl+C 触发) 终止前台进程
SIGSTOP 19 停止(挂起) 暂停进程,进程无法捕获
SIGCONT 18 继续 恢复被 SIGSTOP 暂停的进程
SIGHUP 1 挂断 终端断开时发送,常导致进程退出

SIGTERM vs SIGKILL(关键区别)

  • SIGTERM(15):给进程"体面退出的机会",进程可以保存状态、清理资源后再退出。优先使用
  • SIGKILL(9):强制立刻杀掉,进程无法做任何清理,可能造成数据丢失或留下残留。仅在 SIGTERM 无效时才用。

5.3 kill —— 按 PID 发信号

kill <pid>          # 默认发 SIGTERM(15)
kill -15 <pid>      # 显式 SIGTERM
kill -9 <pid>       # SIGKILL 强制杀
kill -SIGTERM <pid> # 用名称
kill -l             # 列出所有信号
# 查找并结束某进程
ps -ef | grep httpd
kill 1234           # 先优雅终止
kill -9 1234        # 无效才强制

5.4 pkill —— 按名称发信号

pkill httpd              # 结束所有名字含 httpd 的进程(发 SIGTERM)
pkill -9 httpd           # 强制结束
pkill -u username        # 结束某用户的所有进程
pkill -f "pattern"       # 按完整命令行匹配

还有 killall 名称 也可按名字结束(用法类似 pkill)。

杀进程的建议顺序:先用 SIGTERM(kill),不行再用 SIGKILL(kill -9)。不要一上来就 -9

参考:man 1 killman 1 pkillman 7 signal


六、前台 / 后台作业控制

6.1 前台 vs 后台

  • 前台(Foreground):进程占用当前终端,命令执行完才能输入下一条(默认)。
  • 后台(Background):进程在后台运行,终端可以继续输入其他命令。

6.2 把进程放到后台:&

command &         # 在命令后加 & 让其在后台运行
sleep 100 &       # 示例:后台运行一个睡眠 100 秒的进程

6.3 作业控制:jobs / fg / bg

jobs                # 查看当前终端的后台作业(带作业号 [1] [2])
jobs -l             # 同时显示 PID
fg %1               # 把作业 1 调回前台(foreground)
bg %1               # 把暂停的作业 1 放到后台继续跑
kill %1             # 按作业号结束

%1% 后面是作业号(jobs 显示的 [1]),不是 PID。

6.4 Ctrl+C 与 Ctrl+Z(关键区别)

按键 发送信号 作用
Ctrl+C SIGINT(2) 中断:终止当前前台进程
Ctrl+Z SIGTSTP(20) 挂起/暂停:把当前前台进程暂停(不终止),回到 shell

示例:运行 sleep 100,按 Ctrl+Z 会暂停它并显示作业号,然后用 bg 放后台或 fg 调回前台。

sleep 100
# 按 Ctrl+Z  →  [1]+  Stopped  sleep 100
jobs            # 看到作业 1 已停止
bg %1           # 放到后台继续
jobs            # 看到 [1]+  Running

6.5 nohup —— 关闭终端也不中断

普通后台进程&)在关闭终端/退出 shell 时可能被 SIGHUP 信号终止。用 nohup(no hang up)可以让进程忽略 SIGHUP,即使退出终端也继续运行。

nohup command &          # 后台运行并忽略挂断信号
nohup myapp > app.log 2>&1 &   # 常见:输出重定向到日志,后台运行
nohup ./start.sh &       # 服务器上长驻脚本常用
  • nohup 默认把输出写到 nohup.out,可用 > 重定向到指定文件。
  • 适合需要在登出后仍持续运行的任务(如启动服务、长时间任务)。

参考:man 1 bash(Job Control)、man 1 nohup菜鸟教程 - Linux 进程管理


七、systemd 入门:systemctl 与开机自启

systemd 是现代 Linux(RHEL/Rocky、Ubuntu 等)的系统与服务管理器,是 PID 1 进程。它管理系统的所有服务、启动项。

7.1 单元(Unit)

systemd 管理的对象叫单元(Unit),常见类型:

单元类型 后缀 说明
服务 .service 服务/守护进程
挂载点 .mount 文件系统挂载
套接字 .socket 网络/本地套接字
目标 .target 一组单元的集合(如 multi-user.target)
定时器 .timer 定时任务

7.2 systemctl 常用操作(管理服务)

sudo systemctl start httpd         # 启动服务
sudo systemctl stop httpd          # 停止服务
sudo systemctl restart httpd       # 重启服务
sudo systemctl reload httpd        # 重载配置(不中断服务)
sudo systemctl status httpd        # 查看服务状态
sudo systemctl enable httpd        # ★开机自启
sudo systemctl disable httpd       # 取消开机自启
sudo systemctl enable --now httpd  # 设置开机自启并立即启动
systemctl is-active httpd          # 是否运行中
systemctl is-enabled httpd         # 是否开机自启
systemctl list-units --type=service   # 列出所有服务单元
systemctl list-unit-files --type=service   # 列出所有服务及是否启用

enable vs start 区别start立即启动本次生效;enable 设置开机自启。要让服务"现在运行 + 开机自启",两者都要(或 enable --now)。

7.3 查看服务日志

journalctl -u httpd              # 查看某服务的日志
journalctl -u httpd -f           # 实时跟踪(类似 tail -f)
journalctl -u httpd --since today   # 今天的日志

journalctl 是 systemd 的日志查看工具,-u 指定单元。

参考:man 1 systemctlman 5 systemd.unitRed Hat - 使用 systemd 管理服务菜鸟教程 - Linux systemctl


八、进程优先级:nice / renice

8.1 nice 值是什么

  • nice 值范围 -20 ~ 19数值越小优先级越高
  • 默认 nice 值是 0
  • 只有 root 能设置负值(提高优先级);普通用户只能设正值(降低自己进程的优先级)。

8.2 nice —— 启动时指定优先级

nice -n 10 command     # 以 nice=10 启动 command(降低优先级)
nice -n -5 command     # 以 nice=-5 启动(提高优先级,需 root)
sudo nice -n -10 myapp

8.3 renice —— 修改已运行进程的优先级

renice -n 5 -p <pid>       # 把 pid 进程 nice 调整为 5
sudo renice -n -5 -p <pid> # root 提高优先级
renice -n 5 -u username    # 调整某用户所有进程

查看进程优先级top 中的 NI 列,或 ps -o pid,nice,cmd

ps -o pid,nice,comm -p <pid>   # 查看指定进程的 nice 值

什么时候用:让"不着急"的后台任务降低优先级(给前台交互让出 CPU),或给关键任务提高优先级。

参考:man 1 niceman 1 renice


九、僵尸进程与孤儿进程

9.1 僵尸进程(Zombie)

僵尸进程(状态 Z):进程已经结束,但由于某种原因父进程没有回收它的退出状态,于是它在进程表中保留一个"尸体"记录。

  • 僵尸进程不再占用 CPU 和内存,但会占用一个 PID 和进程表项
  • 少量僵尸通常无害,但如果大量堆积,会耗尽 PID 资源。
  • 僵尸进程无法用 kill 杀掉(它已经死了),只能让父进程回收(或杀掉父进程,由 init/systemd 接管回收)。

产生原因:父进程没有调用 wait() 系统调用回收子进程的退出状态(常见于编程 bug)。

# 查看僵尸进程(状态列为 Z)
ps aux | grep defunct
top         # 第二行 Tasks 里看 zombie 数量

处理僵尸进程

# 找到僵尸进程的父进程
ps -o pid,ppid,stat,cmd -p <zombie_pid>

# 僵尸进程已无法直接 kill,尝试:
# 1. 让父进程回收:结束父进程(父进程结束后由 systemd/init 接管回收)
# 2. 若父进程是 init 会自己回收;顽固僵尸通常需要重启相关服务或重启系统

9.2 孤儿进程(Orphan)

  • 孤儿进程:父进程先于子进程结束,子进程被"收养"为 PID 1(systemd/init)的子进程
  • 孤儿进程会被 init/systemd 收养并负责回收,不是问题
  • 与僵尸不同,孤儿进程还在正常运行,只是换了个父进程。

一句话区分

  • 僵尸:子进程死了,父进程没回收 → 残留记录。
  • 孤儿:父进程先死,子进程还活着 → 被 init 收养。

参考:man 7 signalRed Hat - 使用 systemd 管理服务


十、总结与练习

10.1 核心速查

需求 命令
查看所有进程 ps -ef / ps aux
实时监控 top / htop
进程树 pstree -p
优雅结束进程 kill <pid>
强制结束进程 kill -9 <pid>
按名称结束 pkill 名称
后台运行 command &
查看作业 jobs
调回前台 / 放后台 fg %1 / bg %1
挂起 / 中断 Ctrl+Z / Ctrl+C
登出后继续运行 nohup command &
启动/停止服务 sudo systemctl start/stop 服务
开机自启 sudo systemctl enable 服务
查看服务日志 journalctl -u 服务
设置优先级 nice -n / renice -n
查看僵尸进程 `ps aux

10.2 动手练习建议

# 1. 查看进程
ps -ef | head
top

# 2. 后台与作业控制
sleep 300 &
sleep 200
# 按 Ctrl+Z 挂起
jobs
bg %1; fg %1

# 3. 结束进程
sleep 500 &
echo $!             # 上一条后台进程的 PID
kill <那个PID>

# 4. nohup 长驻
nohup sleep 600 > /dev/null 2>&1 &

# 5. systemd 服务
sudo systemctl status sshd
systemctl list-unit-files --type=service | head

# 6. 优先级
ps -o pid,nice,comm -p $$
nice -n 10 sleep 100 &
renice -n 5 -p $$

# 7. 查看僵尸
ps aux | grep -c defunct

提示:练习请在虚拟机(如 Rocky Linux)中进行。killsystemctlrenice 等命令需注意权限(root 可操作所有进程)。


参考资料