Linux 进程管理完全指南
概述
Linux 进程管理是系统运维和后端开发中最核心的技能之一。理解进程的生命周期、进程间通信、守护进程管理,以及如何使用系统工具监控和调优进程,是排查生产环境问题和优化服务器性能的基础。本文从进程基础概念入手,涵盖 ps、top、kill、systemctl 等核心命令的使用,以及进程状态、D-Bus 通信等进阶主题。
基础语法
在 Linux 中,所有运行中的程序都表现为进程,每个进程有一个唯一的 PID(进程标识符)。进程可以是前台运行(占用终端)也可以后台运行。父进程可以创建子进程,形成进程树。进程有多种状态:运行中(R)、可中断睡眠(S)、不可中断睡眠(D)、停止(T)、僵尸(Z)。
- ps:静态查看当前进程快照,aux 选项显示所有进程详细信息。
- top/htop:实时动态监控进程资源占用,htop 提供更友好的交互界面。
- kill/pkill/killall:向进程发送信号,SIGTERM(15)请求优雅退出,SIGKILL(9)强制终止。
- systemctl:管理 systemd 服务的启动、停止、重启和状态查看。
- nohup/setsid:让进程在终端关闭后继续运行,不接收 SIGHUP 信号。
进程间通信(IPC)机制包括管道(pipe)、信号(signal)、套接字(socket)、共享内存、消息队列等,是构建复杂系统的基础。
完整代码示例+注释
# === ps 命令:静态进程查看 ===
ps aux # 显示所有进程的完整格式(BSD 语法)
ps -ef # 显示所有进程的完整格式(System V 语法)
ps -ef --sort=-pcpu | head -11 # 按 CPU 使用率排序(前10)
ps -ef --sort=-pmem | head -11 # 按内存使用率排序(前10)
查看特定用户的进程
ps -u ubuntu -f
查找特定进程(结合 grep)
ps aux | grep nginx | grep -v grep
查看进程树(了解父子关系)
pstree -ap 1234 # 查看 PID 1234 的进程树
pstree -pu # 显示所有进程的进程树
=== top 命令:实时监控 ===
top # 实时动态监控(默认 3 秒刷新)
top -d 1 # 设置刷新间隔为 1 秒
top -p 1234 # 只监控指定 PID 的进程
top -u ubuntu # 只显示指定用户的进程
top 交互命令(运行中按)
M — 按内存排序
P — 按 CPU 排序
c — 显示完整命令路径
k — 发送信号给进程
r — 调整进程优先级(renice)
q — 退出
=== 进程优先级 ===
nice 值范围 -20 到 19,值越小优先级越高
nice -n 10 ./script.sh # 以 nice 值 10 启动进程(较低优先级)
renice -n 5 -p 1234 # 调整运行中进程的 nice 值
renice -n -10 -u ubuntu # 调整用户所有进程的优先级
=== 信号控制 ===
kill -l # 列出所有可用信号及编号
kill -SIGTERM 1234 # 向进程 1234 发送 SIGTERM(优雅终止)
kill -SIGKILL 1234 # 发送 SIGKILL(强制杀死,无法捕获)
kill -SIGSTOP 1234 # 暂停进程(相当于 Ctrl+Z)
kill -SIGCONT 1234 # 继续运行被暂停的进程
pkill:按名称发送信号
pkill -SIGTERM nginx # 优雅重启所有 nginx 进程
pkill -9 -f "python.*app" # 杀死所有匹配 "python.*app" 的进程
=== systemd 服务管理 ===
systemctl status nginx # 查看 nginx 服务状态
systemctl start nginx # 启动 nginx
systemctl stop nginx # 停止 nginx
systemctl restart nginx # 重启 nginx(先停后启)
systemctl reload nginx # 重新加载配置(不中断连接)
systemctl enable nginx # 设置开机自启动
systemctl disable nginx # 取消开机自启动
systemctl list-unit-files # 列出所有服务及其启用状态
查看服务日志
journalctl -u nginx -f # 实时跟踪 nginx 日志
journalctl -u nginx --since "1 hour ago" # 查看最近1小时的日志
=== nohup 和后台运行 ===
nohup python app.py > app.log 2>&1 &
nohup 阻止 SIGHUP 信号,关掉终端不会终止进程
> app.log 将标准输出重定向到文件
2>&1 将标准错误也重定向到标准输出
& 表示后台运行
查看后台任务
jobs # 查看当前终端的后台任务
bg # 将暂停的任务放到后台继续运行
fg # 将后台任务调回前台
=== 进程间通信示例:管道 ===
mkfifo /tmp/my_pipe # 创建命名管道(FIFO)
echo "hello" > /tmp/my_pipe & # 后台写入
cat /tmp/my_pipe # 阻塞读取
匿名管道(子进程继承)
ps aux | grep python # ps 输出通过管道传给 grep
运行效果
执行 ps aux | grep nginx 会显示所有 nginx 相关的进程,包括进程所有者、PID、CPU 和内存占用、命令详情。top 命令进入交互界面后,按 M 键按内存排序可以看到最耗费资源的进程列表,按 k 键再输入进程号和信号编号可以直接在界面上终止进程。
systemctl enable nginx 后,每次服务器重启 nginx 会自动启动,无需手动干预。journalctl -u nginx -f 相当于 tail -f /var/log/nginx/access.log 的 systemd 版本,但支持更灵活的日志过滤和时间范围选择。nohup 方式启动的后台进程可以通过查看 app.log 文件确认运行状态,通过 kill PID 正常终止。
常见问题
Q1:进程处于 D 状态(不可中断睡眠)怎么办
D 状态(Uninterruptible Sleep)通常是进程在等待 I/O 操作完成(如磁盘、网络存储),无法被信号中断。大多数情况下只需等待 I/O 完成就会自动恢复。如果长时间处于 D 状态,可能是硬件故障(如硬盘 SMART 错误、网络存储断连),需要检查硬件健康状态和存储连接。
Q2:如何查看某个进程的子进程
用 pstree -p PID 可以清晰看到该进程的完整进程树。也可以用 ps -ef | grep PPID(父进程ID)来查找某个进程的子进程。进程的 PPID(父进程ID)字段记录了创建它的父进程,init/systemd 的 PID 为 1 是所有孤儿进程的收养者。
Q3:SIGTERM 和 SIGKILL 的区别是什么
SIGTERM(15)是请求终止信号,进程可以捕获并执行清理操作(如关闭文件句柄、保存状态)后再退出,是优雅终止的推荐方式。SIGKILL(9)是强制杀死信号,进程无法捕获或忽略,会立即终止,来不及做清理工作,可能造成临时文件或数据不一致。应该优先使用 SIGTERM,只有在 SIGTERM 无效时才使用 SIGKILL。
Q4:僵尸进程如何处理
僵尸进程是子进程已退出但父进程没有调用 wait() 收集其退出状态的进程。僵尸进程不占用 CPU 和内存(只占用进程表条目),kill 对其无效。处理方法是找到僵尸进程的父进程(PPID),终止父进程后僵尸进程会被 init 收养并自动清理。如果父进程是重要服务无法终止,则需要修复父进程中的 wait() 调用逻辑。
延伸阅读
- Linux man pages:ps(1)、top(1)、kill(1)、signal(7) 等 man 手册提供了完整的命令选项和信号说明。
- systemd 官方文档:https://www.freedesktop.org/wiki/Software/systemd/ — 了解 systemd 的设计哲学和高级功能。
- /proc 文件系统:通过 /proc/PID/status、/proc/PID/fd 等虚拟文件可以直接读取内核级的进程信息。