Linux 进程管理
进程是正在运行的程序实例。本章将介绍如何查看、管理和控制进程。
进程基础
什么是进程?
进程是程序的一次执行过程,包括:
- PID:进程 ID,唯一标识一个进程
- PPID:父进程 ID
- UID:运行进程的用户 ID
- 状态:运行、睡眠、停止、僵尸等
- 优先级:决定 CPU 调度顺序
进程状态
| 状态 | 说明 |
|---|---|
| R (Running) | 正在运行或准备运行 |
| S (Sleeping) | 睡眠状态,等待事件 |
| D (Disk Sleep) | 不可中断的睡眠 |
| Z (Zombie) | 僵尸进程,已结束但未被回收 |
| T (Stopped) | 已停止 |
| I (Idle) | 空闲状态 |
查看进程
ps - 查看进程状态
ps # 显示当前终端的进程
ps aux # 显示所有进程的详细信息
ps -ef # 标准格式显示所有进程
ps -u username # 显示指定用户的进程
ps -p PID # 显示指定 PID 的进程
ps -C process_name # 显示指定名称的进程
ps aux --sort=-%mem # 按内存使用排序
ps aux --sort=-%cpu # 按 CPU 使用排序
输出字段解释:
ps aux
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 1 0.0 0.1 169424 11200 ? Ss Mar15 0:05 /sbin/init
| 字段 | 含义 |
|---|---|
| USER | 进程所有者 |
| PID | 进程 ID |
| %CPU | CPU 使用率 |
| %MEM | 内存使用率 |
| VSZ | 虚拟内存大小(KB) |
| RSS | 实际物理内存(KB) |
| TTY | 终端 |
| STAT | 进程状态 |
| START | 启动时间 |
| TIME | 累计 CPU 时间 |
| COMMAND | 命令名称 |
解释:
ps aux是最常用的组合,a显示所有用户进程,u显示用户信息,x显示无终端进程STAT列可能包含额外字符:<(高优先级)、N(低优先级)、L(有锁定页面)、s(会话领导者)、+(前台进程组)
top - 动态查看进程
top # 启动 top
top -u username # 只显示指定用户的进程
top -p PID # 只显示指定进程
top -d 5 # 设置刷新间隔为 5 秒
交互命令:
| 快捷键 | 功能 |
|---|---|
q | 退出 |
h | 帮助 |
k | 终止进程(输入 PID) |
r | 修改优先级 |
M | 按内存排序 |
P | 按 CPU 排序 |
T | 按时间排序 |
c | 显示完整命令 |
1 | 显示各 CPU 核心使用率 |
z | 彩色显示 |
解释:top 是实时监控的首选工具,按 M 或 P 可以快速找到占用资源最多的进程。
htop - 增强版进程查看器
# 安装
sudo apt install htop # Ubuntu/Debian
sudo yum install htop # CentOS/RHEL
htop # 启动 htop
htop -u username # 只显示指定用户
特点:
- 彩色显示,更直观
- 支持鼠标操作
- 可以直接操作进程(终止、修改优先级)
- 显示 CPU 核心负载条
pgrep - 按名称查找进程
pgrep nginx # 查找 nginx 进程的 PID
pgrep -l nginx # 显示进程名
pgrep -u root nginx # 查找 root 用户的 nginx 进程
pgrep -P PPID # 查找指定父进程的子进程
pidof - 查找进程 PID
pidof nginx # 查找 nginx 进程的 PID
pidof -s nginx # 只返回一个 PID
pstree - 显示进程树
pstree # 树形显示进程
pstree -p # 显示 PID
pstree -u # 显示用户
pstree -h # 高亮当前进程及其祖先
pstree PID # 显示指定进程的子树
终止进程
kill - 发送信号
kill PID # 发送 TERM 信号(默认)
kill -9 PID # 发送 KILL 信号(强制终止)
kill -15 PID # 发送 TERM 信号(优雅终止)
kill -l # 列出所有信号
kill -SIGNAL PID # 发送指定信号
常用信号:
| 信号 | 数字 | 说明 |
|---|---|---|
| SIGHUP | 1 | 挂起(重新读取配置) |
| SIGINT | 2 | 中断(Ctrl+C) |
| SIGQUIT | 3 | 退出 |
| SIGKILL | 9 | 强制终止(不可捕获) |
| SIGTERM | 15 | 终止(默认,可捕获) |
| SIGCONT | 18 | 继续 |
| SIGSTOP | 19 | 停止 |
| SIGUSR1 | 10 | 用户自定义信号1 |
解释:
SIGTERM(15)是默认信号,进程可以捕获并做清理工作后退出SIGKILL(9)是强制终止,进程无法捕获,可能导致数据丢失- 应该先尝试
SIGTERM,只有在进程无响应时才使用SIGKILL
killall - 按名称终止进程
killall nginx # 终止所有 nginx 进程
killall -9 nginx # 强制终止
killall -u user nginx # 终止指定用户的 nginx 进程
killall -i nginx # 交互式终止
pkill - 按模式终止进程
pkill nginx # 终止 nginx 进程
pkill -u user # 终止指定用户的所有进程
pkill -f "python script.py" # 匹配完整命令行
pkill -9 nginx # 强制终止
后台进程
& - 后台运行
command & # 在后台运行命令
nohup command & # 忽略挂断信号,退出终端后继续运行
nohup command > output.log 2>&1 & # 重定向输出
jobs - 查看后台任务
jobs # 列出当前 shell 的后台任务
jobs -l # 显示 PID
fg/bg - 前后台切换
fg %1 # 将任务 1 切换到前台
bg %1 # 将任务 1 切换到后台
Ctrl+Z # 暂停当前前台任务
disown - 移除任务
disown %1 # 从 jobs 中移除任务
disown -h %1 # 标记任务不受 SIGHUP 影响
进程优先级
nice - 以指定优先级启动
nice -n 10 command # 以优先级 10 启动(较低)
nice -n -5 command # 以优先级 -5 启动(较高,需要 root)
解释:
- 优先级范围:-20(最高)到 19(最低)
- 默认优先级为 0
- 普通用户只能设置正数(降低优先级)
- Root 用户可以设置负数(提高优先级)
renice - 修改运行中进程的优先级
renice 5 -p PID # 修改进程优先级
renice 5 -u username # 修改用户所有进程的优先级
renice 5 -g groupname # 修改组所有进程的优先级
系统监控
free - 查看内存
free # 显示内存使用情况
free -h # 人性化显示
free -m # 以 MB 为单位
free -s 5 # 每 5 秒刷新一次
输出解释:
total used free shared buff/cache available
Mem: 7.7G 2.1G 3.2G 256M 2.3G 5.0G
Swap: 2.0G 0B 2.0G
| 字段 | 含义 |
|---|---|
| total | 总内存 |
| used | 已使用 |
| free | 空闲 |
| shared | 共享内存 |
| buff/cache | 缓冲/缓存 |
| available | 可用内存(考虑可回收缓存) |
解释:Linux 会积极使用内存做缓存,所以 available 比单纯的 free 更能反映实际可用内存。
vmstat - 系统状态
vmstat # 显示系统状态
vmstat 5 # 每 5 秒刷新
vmstat 5 3 # 刷新 3 次
iostat - I/O 状态
iostat # 显示 CPU 和 I/O 统计
iostat -x # 详细统计
iostat 5 # 每 5 秒刷新
netstat - 网络状态
netstat -tulpn # 显示监听的端口
netstat -an # 显示所有连接
netstat -rn # 显示路由表
ss - 替代 netstat
ss -tulpn # 显示监听的端口
ss -s # 显示统计摘要
ss -an # 显示所有连接
lsof - 列出打开的文件
lsof -i :80 # 查看占用 80 端口的进程
lsof -u username # 查看用户打开的文件
lsof -p PID # 查看进程打开的文件
lsof /var/log/syslog # 查看打开日志文件的进程
uptime - 系统运行时间
uptime
# 10:30:45 up 5 days, 3:21, 2 users, load average: 0.50, 0.30, 0.10
解释:
up 5 days:运行 5 天2 users:当前登录用户数load average:系统负载(1分钟、5分钟、15分钟平均值)- 负载值接近 CPU 核心数时系统比较繁忙
w - 显示登录用户
w
# 10:30:45 up 5 days, 3:21, 2 users, load average: 0.50, 0.30, 0.10
# USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
# user pts/0 192.168.1.100 10:00 5.00s 0.10s 0.00s w
定时任务
crontab - 定时任务管理
crontab -l # 列出当前用户的定时任务
crontab -e # 编辑定时任务
crontab -r # 删除所有定时任务
crontab -u user -l # 列出指定用户的定时任务(需要 root)
cron 表达式:
* * * * * command
│ │ │ │ │
│ │ │ │ └─ 星期几 (0-7, 0 和 7 都是周日)
│ │ │ └─── 月份 (1-12)
│ │ └───── 日期 (1-31)
│ └─────── 小时 (0-23)
└───────── 分钟 (0-59)
示例:
# 每分钟执行
* * * * * /path/to/script.sh
# 每小时执行
0 * * * * /path/to/script.sh
# 每天凌晨 2 点执行
0 2 * * * /path/to/script.sh
# 每周一早上 8 点执行
0 8 * * 1 /path/to/script.sh
# 每月 1 号凌晨执行
0 0 1 * * /path/to/script.sh
# 每 5 分钟执行
*/5 * * * * /path/to/script.sh
# 工作日早上 9 点执行
0 9 * * 1-5 /path/to/script.sh
at - 一次性定时任务
at 10:30 # 在 10:30 执行
at now + 1 hour # 1 小时后执行
at 10:30 tomorrow # 明天 10:30 执行
atq # 列出待执行任务
atrm JOB_NUMBER # 删除任务
实践案例
查找并终止占用端口的进程
# 查找占用 8080 端口的进程
sudo lsof -i :8080
# 或
sudo netstat -tulpn | grep 8080
# 终止进程
sudo kill -9 PID
查找 CPU 使用率最高的进程
# 使用 top
top -o %CPU
# 使用 ps
ps aux --sort=-%cpu | head -10
查找内存使用最高的进程
# 使用 top
top -o %MEM
# 使用 ps
ps aux --sort=-%mem | head -10
后台运行长期任务
# 使用 nohup
nohup ./long_task.sh > output.log 2>&1 &
# 使用 screen
screen -S task
./long_task.sh
# Ctrl+A+D 分离会话
screen -r task # 重新连接
# 使用 tmux
tmux new -s task
./long_task.sh
# Ctrl+B+D 分离会话
tmux attach -t task # 重新连接
小结
本章我们学习了:
- 进程的概念和状态
- 查看进程(ps、top、htop、pgrep、pstree)
- 终止进程(kill、killall、pkill)
- 后台进程管理(&、nohup、jobs、fg/bg)
- 进程优先级(nice、renice)
- 系统监控(free、vmstat、iostat、netstat、lsof)
- 定时任务(crontab、at)
练习
- 使用
ps查看当前系统运行的所有进程 - 使用
top找出占用内存最多的进程 - 后台运行一个命令,然后将其切换到前台
- 创建一个 crontab 任务,每分钟输出当前时间到文件
- 查找并解释
/var/log/syslog文件被哪个进程使用 - 使用
nice以较低优先级运行一个命令