大家好,我是冯哥的缓存。上一篇聊了用 cron 让系统定时自动跑任务。任务跑起来之后,怎么知道它有没有在跑、占了多少资源、卡住了怎么办?这就是今天要聊的进程管理与监控。
进程管理是 Linux 运维基础与实用的技能之一。CPU 突然跑满了、内存不够了、某个程序假死了、服务启动不起来,第一步都是查进程。
💡提示:本文所有命令在 Ubuntu 22.04 / Debian 12 / Fedora 38 / Arch Linux 下验证。
一、进程是什么
程序是磁盘上的文件;进程是程序运行起来之后在内存里的实体。每个进程有一个唯一编号叫PID(Process ID)。
进程的关键属性
属性 | 说明 |
PID | 进程 ID,唯一标识 |
PPID | 父进程 ID,谁启动了它 |
UID/USER | 哪个用户在跑 |
%CPU | CPU 占用百分比 |
%MEM | 内存占用百分比 |
VSZ | 虚拟内存大小(KB) |
RSS | 实际占用物理内存(KB) |
STAT | 进程状态(见下表) |
COMMAND | 启动命令 |
进程状态码
状态码 | 含义 |
R | Running,正在运行或可运行 |
S | Sleeping,等待事件(常见) |
D | Disk Sleep,不可中断睡眠,这种状态无法被 kill -9 杀掉,只能等 IO 完成或重启系统。 |
T | Stopped,被暂停(Ctrl+Z) |
Z | Zombie,僵尸进程(已退出但未被父进程回收) |
I | Idle,空闲内核线程 |
💡提示:状态码后面跟 <表示高优先级,N表示低优先级,s表示会话领导,l表示多线程,+表示前台进程组。
二、ps——查看进程快照
ps(Process Status)输出的是某一时刻的进程列表,不会动态更新。
常用组合
# 查看当前终端的进程
ps
# 查看所有用户的所有进程(常用)
ps aux
# 树形显示父子关系
ps auxf
# 只看某个用户的进程
ps -u fqy0610
# 只看某个名字的进程(模糊匹配)
ps aux | grep nginx
# 找进程 PID,[n] 让 grep 匹配 nginx 但不匹配自身(不显示 grep 自身)
ps aux | grep '[n]ginx'
ps aux 各列含义
USERPID %CPU %MEMVSZRSS TTYSTAT STARTTIME COMMAND
root10.00.1 168700 11800 ?SsJun280:04 /sbin/init
列 | 说明 |
USER | 运行该进程的用户 |
PID | 进程 ID |
%CPU | CPU 使用率 |
%MEM | 内存使用率 |
VSZ | 虚拟内存(KB) |
RSS | 物理内存(KB) |
TTY | 关联的终端,? 表示无终端(后台服务) |
STAT | 进程状态 |
START | 启动时间 |
TIME | 累计 CPU 时间 |
COMMAND | 命令及参数 |
如果 RSS 持续增长,可能说明有内存泄漏。
pgrep 和 pstree
# 只返回 PID,不需要 grep 过滤
pgrep nginx
pgrep -u root sshd# 指定用户
# 树形显示(更清晰)
pstree
pstree -p# 显示 PID
pstree -u# 显示用户名
三、top——实时进程监控
top是内置的实时监控工具,每 3 秒自动刷新。
top
top -u fqy0610# 只显示某用户的进程
top -p 1234,5678# 只监控指定 PID
top 界面解读
top - 11:22:08 up 2 days,3:14,2 users,load average: 0.52, 0.48, 0.43
Tasks: 312 total,1 running, 311 sleeping,0 stopped,0 zombie
%Cpu(s):2.3 us,0.8 sy,0.0 ni, 96.5 id,0.3 wa,0.0 hi,0.1 si
MiB Mem :15940.5 total,4210.3 free,8320.1 used,3410.1 buff/cache
MiB Swap:2048.0 total,1848.2 free,199.8 used.6890.4 avail Mem
字段 | 含义 |
load average | 1/5/15 分钟平均负载,超过 CPU 核数就说明有排队,对于单核,负载 < 1 正常;对于 8 核,负载 < 8 正常。 |
us | 用户空间 CPU 时间 |
sy | 内核空间 CPU 时间 |
wa | IO 等待(高说明磁盘是瓶颈) |
id | 空闲(越高越轻松) |
buff/cache | 文件缓存,系统会自动回收 |
top 交互快捷键
按键 | 作用 |
q | 退出 |
1 | 展开显示每个 CPU 核的使用率 |
M | 按内存使用率排序 |
P | 按 CPU 使用率排序(默认) |
T | 按累计 CPU 时间排序 |
k | 输入 PID 发送信号(杀进程) |
r | 输入 PID 调整优先级(renice) |
f | 选择显示哪些列 |
u | 过滤显示某用户的进程 |
H | 切换显示线程 |
d | 修改刷新间隔 |
Shift+W | 保存配置到 ~/.toprc |
四、htop——更好用的 top
htop是 top 的增强版,彩色界面,支持鼠标点击,功能更强。
# 安装
sudo apt install htop# Debian/Ubuntu
sudo dnf install htop# Fedora/RHEL
sudo pacman -S htop# Arch
# 启动
htop
htop 界面优势
·彩色进度条:CPU、内存使用一目了然
·鼠标支持:点击列名排序,点击进程选中
·树形视图:F5切换进程树
·搜索过滤:/搜索,\过滤
·多选操作:Space标记多个进程
htop 常用快捷键
按键 | 作用 |
F1 | 帮助 |
F2 | 设置(颜色/显示列/CPU meter 样式) |
F3 / / | 搜索进程名 |
F4 | 过滤(只显示匹配的进程) |
F5 | 树形视图切换 |
F6 | 选择排序列 |
F9 | 发送信号(图形化 kill) |
F10 / q | 退出 |
u | 过滤用户 |
Space | 标记/取消标记进程 |
k | 发送信号给选中进程 |
💡提示: htop 的 F2 → Display options → Tree view可以设置默认启动就是树形视图,比 top 更直观。不同版本菜单位置可能略有不同,搜索 Tree view 选项即可。
五、kill——向进程发送信号
kill不只是"杀进程",准确说是向进程发送信号,进程可以选择响应方式。
常用信号
信号编号 | 信号名 | 含义 | 能被忽略? |
1 | SIGHUP | 重新加载配置(不重启进程) | 能 |
2 | SIGINT | 中断(等同于 Ctrl+C) | 能 |
9 | SIGKILL | 强制立即终止 | 不能 |
15 | SIGTERM | 优雅终止(默认) | 能 |
18 | SIGCONT | 继续运行(恢复暂停的进程) | — |
19 | SIGSTOP | 暂停进程(等同于 Ctrl+Z) | 不能 |
** kill -9 是最强手段,但也最危险,优先用kill -15。**
# 默认发送 SIGTERM(优雅退出)
kill 1234
# 强制杀死(进程无法忽略)
kill -9 1234
kill -SIGKILL 1234
# 让进程重新加载配置(nginx/sshd 常用)
kill -1 1234
kill -HUP 1234
# 按进程名发送信号(不需要先查 PID)
pkill nginx
pkill -9 firefox
pkill -HUP sshd
# 向某用户的所有进程发送信号
pkill -u testuser
# killall:按精确名字匹配
killall nginx
killall -9 chrome
⚠️注意:优先用 kill -15(SIGTERM),给进程机会做清理工作(关文件、写日志、释放锁)。只有在进程无响应时才用 kill -9,后者不给进程任何收尾机会。
查 PID 再杀的完整流程
# 方法一:ps + grep + kill
ps aux | grep nginx
kill 12345
# 方法二:pgrep + kill(一步到位)
kill $(pgrep nginx)
# 方法三:pkill(简洁)
pkill nginx
六、nice 和renice——进程优先级
Linux 用nice 值控制进程的 CPU 调度优先级:
·范围:-20(最高优先级)到 +19(最低优先级)
·默认值:0
·普通用户只能调高 nice 值(降低优先级),调低 nice 值(提高优先级)需要 root
# 以低优先级启动(nice 值 +10,让其他任务优先)
nice -n 10 python backup.py
# 以高优先级启动(需要 root)
sudo nice -n -5 ./important_task.sh
# 调整正在运行进程的优先级
renice -n 15 -p 1234# 把 PID 1234 调低优先级
sudo renice -n -5 -p 1234# 提高优先级(需要 root)
# 按进程名批量调整
renice -n 10 -u fqy0610# 调低某用户所有进程的优先级
💡实用场景:跑耗时的编译任务、数据处理脚本时,用 nice -n 19启动,让它在后台慢慢跑,不影响前台操作的流畅度。
七、systemctl——管理系统服务
系统服务(比如 SSH、Nginx、MySQL)由systemd统一管理,systemctl是操控 systemd 的命令。
基础操作
# 查看服务状态(常用)
systemctl status nginx
systemctl status sshd
# 启动/停止/重启
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# 如果服务启动失败,systemctl status 会显示红色 failed 和最后几行错误日志。
# 重新加载配置(不重启进程)
sudo systemctl reload nginx
# 开机自启/禁用自启
sudo systemctl enable nginx
sudo systemctl disable nginx
# 同时启动并设置开机自启
sudo systemctl enable --now nginx
# 强制立即终止(相当于 kill -9)
sudo systemctl kill nginx
# systemctl kill 默认发送 SIGTERM,可以用 --signal 指定其他信号。
查看服务信息
# 列出所有正在运行的服务
systemctl list-units --type=service --state=running
# 列出所有服务(包括未运行的)
systemctl list-units --type=service --all
# 查看开机自启状态
systemctl is-enabled nginx
# 查看服务的日志
journalctl -u nginx
journalctl -u nginx -f# 实时跟踪
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx -n 50# 最近 50 行
服务状态含义
状态 | 说明 |
active (running) | 正在运行 |
active (exited) | 已完成(一次性任务) |
inactive (dead) | 未运行 |
failed | 启动失败 |
activating | 正在启动 |
常用服务名参考
服务 | 常用名 |
SSH 服务 | ssh 或 sshd |
Nginx | nginx |
Apache | apache2(Debian)/ httpd(RHEL) |
MySQL | mysql 或 mysqld |
PostgreSQL | postgresql |
Docker | docker |
防火墙 UFW | ufw |
蓝牙 | bluetooth |
网络管理 | NetworkManager |
如果不知道服务名,用 systemctl list-units --type=service 列出所有服务。
八、后台运行与 nohup
前台和后台
# 正常启动(前台运行,终端被占用)
python server.py
# 在后台启动(加 &)
python server.py &
# 把前台进程推到后台(先 Ctrl+Z 暂停,再 bg 继续)
python server.py
# Ctrl+Z
bg
# 把后台进程拉回前台
fg
fg %1# 指定 job 编号
# 查看后台任务列表
jobs
jobs -l# 显示 PID
nohup——关闭终端后继续跑
普通后台进程(&)在关掉终端或 SSH 断线后会收到 SIGHUP 信号而退出。nohup让进程忽略这个信号:
# 关掉终端也不停
nohup python server.py &
# 输出重定向,nohup 不会自动把进程设为后台,必须加 &(默认输出到 nohup.out)
nohup python server.py > server.log 2>&1 &
# 查看是否还在运行
ps aux | grep server.py
# 找到 PID 后停止
kill $(pgrep -f server.py)
💡提示:如果要长期跑后台服务,推荐用 systemctl(上面第七节)或 screen/tmux管理会话,比 nohup更可控、更好排查。
九、实战排查:CPU/内存跑满怎么办
场景一:CPU 突然 100%
# 第一步:看谁在占 CPU
top# 默认按 CPU 排序
# 或者
ps aux --sort=-%cpu | head -10
# 第二步:确认是哪个进程
ps aux | grep <PID>
# 第三步:看这个进程在干什么
ls -l /proc/<PID>/exe# 查可执行文件路径
cat /proc/<PID>/cmdline | tr '\0' ' '# 查完整命令行
lsof -p <PID> | head -20# 查打开的文件
# 第四步:决定是等待、降优先级还是杀掉
renice -n 19 -p <PID># 先降优先级,给系统喘息机会
kill -15 <PID># 确认要停则优雅终止
场景二:内存不够用(OOM)
# 查内存占用 Top 10
ps aux --sort=-%mem | head -10
# 查系统内存概览
free -h
# 查 OOM Killer 有没有杀过进程(内核日志)
sudo dmesg | grep -i "killed process"
sudo journalctl -k | grep -i oom
# 查 /proc/meminfo 详情
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Cached"
场景三:僵尸进程(Zombie)
僵尸进程已经退出,但父进程没有调用wait()回收,进程表里留了个空壳。僵尸进程本身不占 CPU 和内存,但占用 PID 表条目,大量僵尸会导致 PID 耗尽。
# 查僵尸进程
ps aux | grep Z
ps aux | awk '$8 == "Z"'
# 找父进程
ps -o ppid= -p <僵尸PID># 返回父进程 PID
ps aux | grep <PPID>
# 杀父进程(父进程退出后,僵尸会被 init 回收)
# 如果父进程是 systemd 管理的服务,可以 systemctl restart 服务 来清理。
kill -9 <PPID>
⚠️注意:不要直接 kill -9僵尸进程,僵尸进程已经"死"了,kill 无效。正确方式是通知(kill -17)或重启父进程,让父进程回收它。
十、实用工具补充
以下工具在日常排查中非常有用,按需了解。
vmstat——系统资源概览
vmstat 2 5# 每 2 秒报告一次,共 5 次
字段 | 含义 |
r | 运行队列长度(超过 CPU 核数说明有积压) |
b | 等待 IO 的进程数 |
si/so | swap 换入/换出(频繁则内存严重不足) |
bi/bo | 磁盘读/写块数(高说明 IO 压力大) |
wa | CPU 等待 IO 的比例 |
lsof——查进程打开了什么文件
# 某进程打开的所有文件,lsof 是排查端口冲突的首选工具
lsof -p 1234
# 谁在占用某个端口
sudo lsof -i :8080
sudo lsof -i :80 -i :443
# 谁在用某个文件(卸载磁盘前很有用)
lsof /var/log/syslog
# 某用户打开的文件
lsof -u fqy0610
strace——跟踪进程系统调用(排查神器)
#strace 输出可能很密集,查看网络相关调用
strace -e trace=network -p 1234
# 跟踪进程在调用什么系统调用
strace -p 1234
# 只显示文件相关调用
strace -e trace=file -p 1234
# 启动程序并跟踪
strace python script.py
# 如果只想让某个程序运行一段时间后自动停止
timeout 60s python script.py
# watch 可以定时执行命令并刷新输出,适合监控某个特定进程的状态变化
watch -n 2 "ps aux | grep nginx"
# 如果某个程序经常失控,可以限制其 CPU 运行时间不超过 60 秒
ulimit -t 60
💡提示: strace 对排查"程序卡死/不响应"很有用,能看到进程到底在等什么(文件锁、网络请求、信号等)。
十一、速查表
进程查看
命令 | 作用 |
ps aux | 查所有进程快照 |
ps auxf | 树形显示 |
pgrep nginx | 按名字找 PID |
pstree -p | 进程树(显示 PID) |
top | 实时监控(内置) |
htop | 实时监控(增强版) |
进程控制
命令 | 作用 |
kill <PID> | 优雅终止(SIGTERM) |
kill -9 <PID> | 强制终止(SIGKILL) |
kill -1 <PID> | 重载配置(SIGHUP) |
pkill <name> | 按名终止 |
nice -n 10 cmd | 低优先级启动 |
renice -n 10 -p <PID> | 调整运行中进程优先级 |
后台运行
命令 | 作用 |
cmd & | 后台运行 |
Ctrl+Z | 暂停 |
bg | 继续在后台运行 |
fg | 拉回前台 |
jobs | 查看后台任务列表 |
nohup cmd & | 关终端不停止 |
systemctl 服务管理
命令 | 作用 |
systemctl status <svc> | 查状态 |
systemctl start/stop/restart <svc> | 启停重启 |
systemctl enable --now <svc> | 启动并开机自启 |
journalctl -u <svc> -f | 实时查日志 |
💡提示:如果记不住所有命令,先记住这三条:htop 看资源、kill 停进程、systemctl管服务。
小结
场景 | 推荐工具 |
快速查谁在占 CPU/内存 | htop(彩色直观)或 top |
找某个服务的 PID | pgrep nginx |
优雅停止进程 | kill <PID> 或 pkill <name> |
强制终止卡死进程 | kill -9 <PID> |
管理系统服务 | systemctl,搭配 journalctl 查日志 |
排查端口被谁占用 | sudo lsof -i :<port> |
后台跑不间断的任务 | nohup cmd & 或 写成 systemd service |
下篇预告:Linux 系统日志篇——journalctl、/var/log/目录结构、如何从日志里找出系统问题的根因。看日志是 Linux 排错的最终武器,掌握了这套技能,绝大多数问题都能追查出来。