⚙️ 第09课:进程管理

阶段二:用户与进程 第3/6课

📚 课程目标

一、进程基础

1.1 什么是进程

进程是程序的执行实例,包含代码、数据、堆栈、文件描述符等资源。每个进程有唯一的PID(Process ID),由内核分配。

1.2 进程状态

状态代码说明
RunningR正在CPU上执行或等待调度
SleepingS可中断睡眠,等待事件
Disk SleepD不可中断睡眠(通常等IO)
StoppedT被信号暂停
ZombieZ已终止但父进程未回收
IdleI空闲内核线程

1.3 进程优先级

Linux使用nice值(-20到19)影响进程调度优先级。nice值越低,优先级越高。默认为0。

优先级: -20(最高) ←─────── 0 ───────→ 19(最低)
  │         │                          │
  │    仅root可设置               任何用户可设置
  └── 系统进程                     └── 后台批处理

二、查看进程

2.1 ps命令

$ ps aux | head -15
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1  22352 13440 ?        Ss   02:15   0:04 /sbin/init showopts
root           2  0.0  0.0      0     0 ?        S    02:15   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        S    02:15   0:00 [pool_workqueue_release]
root           4  0.0  0.0      0     0 ?        I<   02:15   0:00 [kworker/R-rcu_g]
root           5  0.0  0.0      0     0 ?        I<   02:15   0:00 [kworker/R-rcu_p]
root           6  0.0  0.0      0     0 ?        I<   02:15   0:00 [kworker/R-slub_]
root           7  0.0  0.0      0     0 ?        I<   02:15   0:00 [kworker/R-netns]
root          10  0.0  0.0      0     0 ?        I<   02:15   0:00 [kworker/0:0H-events_highpri]
root          12  0.0  0.0      0     0 ?        I<   02:15   0:00 [kworker/R-mm_pe]
root          13  0.0  0.0      0     0 ?        I    02:15   0:00 [rcu_tasks_kthread]
root          14  0.0  0.0      0     0 ?        I    02:15   0:00 [rcu_tasks_rude_kthread]
root          15  0.0  0.0      0     0 ?        I    02:15   0:00 [rcu_tasks_trace_kthread]
root          16  0.0  0.0      0     0 ?        S    02:15   0:05 [ksoftirqd/0]
root          17  0.1  0.0      0     0 ?        I    02:15   1:59 [rcu_preempt]
# 常用ps格式
ps aux            # BSD风格,显示所有进程
ps -ef            # System V风格
ps -e --forest    # 树形显示进程关系
ps -eo pid,ppid,ni,stat,cmd | head  # 自定义列

# 列含义:
# USER: 用户
# PID: 进程ID
# %CPU: CPU使用率
# %MEM: 内存使用率
# VSZ: 虚拟内存大小(KB)
# RSS: 物理内存大小(KB)
# STAT: 进程状态
# START: 启动时间
# TIME: CPU时间
# COMMAND: 命令

2.2 top/htop

$ top -bn1 | head -20
top - 21:50:49 up 19:35,  0 user,  load average: 0.48, 0.59, 0.65
Tasks: 150 total,   2 running, 148 sleeping,   0 stopped,   0 zombie
%Cpu(s): 13.6 us,  0.0 sy,  0.0 ni, 86.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st 
MiB Mem :   7685.9 total,   1448.9 free,   2131.8 used,   4465.2 buff/cache     
MiB Swap:  10180.0 total,  10019.5 free,    160.5 used.   5554.1 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 544551 root      20   0   22.4g   1.1g  64524 S   9.1  14.2  47:09.87 node
      1 root      20   0   22352  13440   9476 S   0.0   0.2   0:04.12 systemd
      2 root      20   0       0      0      0 S   0.0   0.0   0:00.02 kthreadd
      3 root      20   0       0      0      0 S   0.0   0.0   0:00.00 pool_wo+
      4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+
      5 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+
      6 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+
      7 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+
     10 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+
     12 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+
     13 root      20   0       0      0      0 I   0.0   0.0   0:00.00 rcu_tas+
     14 root      20   0       0      0      0 I   0.0   0.0   0:00.00 rcu_tas+
     15 root      20   0       0      0      0 I   0.0   0.0   0:00.00 rcu_tas+
# top交互命令
# M: 按内存排序
# P: 按CPU排序
# T: 按时间排序
# k: 杀进程
# r: renice
# 1: 显示所有CPU
# q: 退出

# htop(更友好的top)
sudo apt install htop
htop

2.3 pstree

$ pstree | head -20
systemd-+-ModemManager---3*[{ModemManager}]
        |-YDLive-+-YDService---22*[{YDService}]
        |        `-8*[{YDLive}]
        |-2*[agetty]
        |-barad_agent-+-barad_agent
        |             `-barad_agent---5*[{barad_agent}]
        |-chronyd---chronyd
        |-containerd---8*[{containerd}]
        |-containerd-shim-+-nginx---2*[nginx]
        |                 `-12*[{containerd-shim}]
        |-cosfs---2*[{cosfs}]
        |-cron
        |-dbus-daemon
        |-dockerd-+-docker-proxy---4*[{docker-proxy}]
        |         |-docker-proxy---5*[{docker-proxy}]
        |         `-13*[{dockerd}]
        |-multipathd---6*[{multipathd}]
        |-networkd-dispat
        |-nginx---2*[nginx]
        |-polkitd---3*[{polkitd}]

三、进程信号

3.1 常见信号

$ kill -l
0
HUP
INT
QUIT
ILL
TRAP
ABRT
BUS
FPE
KILL
USR1
SEGV
USR2
PIPE
ALRM
TERM
16
CHLD
CONT
STOP
TSTP
TTIN
TTOU
URG
XCPU
XFSZ
VTALRM
PROF
WINCH
IO
PWR
SYS
32
33
RTMIN
RTMIN+1
RTMIN+2
RTMIN+3
RTMIN+4
RTMIN+5
RTMIN+6
RTMIN+7
RTMIN+8
RTMIN+9
RTMIN+10
RTMIN+11
RTMIN+12
RTMIN+13
RTMIN+14
RTMIN+15
RTMAX-14
RTMAX-13
RTMAX-12
RTMAX-11
RTMAX-10
RTMAX-9
RTMAX-8
RTMAX-7
RTMAX-6
RTMAX-5
RTMAX-4
RTMAX-3
RTMAX-2
RTMAX-1
RTMAX
信号编号默认行为用途
SIGHUP1终止挂起/重载配置
SIGINT2终止中断(Ctrl+C)
SIGQUIT3终止+core退出(Ctrl+\)
SIGKILL9终止强制杀死(不可捕获)
SIGTERM15终止优雅终止(默认信号)
SIGSTOP19停止暂停(不可捕获)
SIGCONT18继续恢复暂停的进程
SIGUSR1/210/12终止用户自定义信号

3.2 kill命令

# 发送SIGTERM(优雅终止)
kill PID
kill -15 PID

# 强制杀死(最后手段!)
kill -9 PID

# 发送其他信号
kill -HUP PID     # 重载配置
kill -STOP PID    # 暂停
kill -CONT PID    # 恢复

# 按名称杀进程
killall nginx
pkill -f "python app.py"

# 杀死进程组
kill -- -PGID
kill -9是强制终止,进程来不及清理资源(临时文件、socket等),可能导致数据丢失。优先使用kill(SIGTERM)让进程优雅退出。

四、作业控制

# 后台运行
command &                # 后台执行
nohup command &          # 退出终端后继续运行

# 作业控制
Ctrl+Z                   # 暂停当前作业
jobs                     # 查看作业列表
bg %1                    # 将作业1放到后台
fg %1                    # 将作业1调到前台
disown %1                # 使作业脱离终端

# 使用tmux/screen管理长期任务
tmux new -s work         # 创建会话
tmux attach -t work      # 恢复会话

五、进程优先级调整

$ ps -eo pid,ni,comm | head -10
PID  NI COMMAND
      1   0 systemd
      2   0 kthreadd
      3   0 pool_workqueue_release
      4 -20 kworker/R-rcu_g
      5 -20 kworker/R-rcu_p
      6 -20 kworker/R-slub_
      7 -20 kworker/R-netns
     10 -20 kworker/0:0H-events_highpri
     12 -20 kworker/R-mm_pe
# 以指定nice值启动
nice -n 10 ./backup.sh      # 低优先级运行备份
nice -n -5 ./realtime-app   # 高优先级(需要root)

# 修改运行中进程的nice值
renice -n 5 -p PID          # 降低优先级
renice -n -3 -p PID         # 提高优先级(需要root)

# 修改用户所有进程的nice值
renice -n 10 -u username

六、/proc/PID目录

# 查看进程详细信息
ls /proc/1/                 # init进程
cat /proc/1/status          # 进程状态
cat /proc/1/cmdline         # 完整命令行
cat /proc/1/environ         # 环境变量
ls -la /proc/1/fd/          # 打开的文件描述符
cat /proc/1/maps            # 内存映射
cat /proc/1/io              # IO统计

七、故障排查

❌ 问题:僵尸进程(Zombie)

# 查找僵尸进程
ps aux | awk '$8=="Z"'

# 杀死僵尸的父进程
kill -9 $(ps -o ppid= -p ZOMBIE_PID)

# 如果父进程是init(PID 1),僵尸会自动回收

❌ 问题:进程占满CPU

# 找到高CPU进程
top -bn1 | head -20
ps aux --sort=-%cpu | head

# 分析进程
strace -p PID    # 跟踪系统调用
lsof -p PID      # 查看打开的文件

# 限制CPU使用
cpulimit -l 50 -p PID   # 限制到50%

八、练习

📝 练习1:进程管理实战

# 1. 找出占用内存最多的5个进程
ps aux --sort=-%mem | head -6

# 2. 找出所有僵尸进程
ps aux | awk '$8~/Z/'

# 3. 查看某进程的所有线程
ps -T -p 1 | head

# 4. 后台运行一个长时间任务
sleep 300 &
jobs
fg %1    # 调回前台
Ctrl+C   # 终止
🏆

成就解锁:进程调度员

✅ 理解进程状态与生命周期

✅ 掌握ps/top/htop查看进程

✅ 学会使用信号控制进程

✅ 了解优先级与作业控制

九、进程监控脚本

#!/bin/bash
# proc-monitor.sh - 进程监控脚本
THRESHOLD_CPU=80
THRESHOLD_MEM=80

echo "===== 进程监控报告 ====="
echo "时间: $(date)"
echo

# 高CPU进程
echo "--- 高CPU进程 (>${THRESHOLD_CPU}%) ---"
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | awk -v t=$THRESHOLD_CPU 'NR>1 && $3+0>t {printf "PID:%-6s User:%-8s CPU:%-5s MEM:%-5s Cmd:%s\n", $1,$2,$3"%",$4"%",$5}'

echo

# 高内存进程
echo "--- 高内存进程 (>${THRESHOLD_MEM}%) ---"
ps -eo pid,user,%cpu,%mem,comm --sort=-%mem | awk -v t=$THRESHOLD_MEM 'NR>1 && $4+0>t {printf "PID:%-6s User:%-8s CPU:%-5s MEM:%-5s Cmd:%s\n", $1,$2,$3"%",$4"%",$5}'

echo

# 僵尸进程
echo "--- 僵尸进程 ---"
zombies=$(ps aux | awk '$8~/Z/' | wc -l)
if [ "$zombies" -gt 0 ]; then
    echo "⚠️ 发现 $zombies 个僵尸进程!"
    ps aux | awk '$8~/Z/'
else
    echo "✅ 无僵尸进程"
fi

# D状态进程(可能IO瓶颈)
echo
echo "--- D状态进程(不可中断睡眠) ---"
dstate=$(ps aux | awk '$8~/D/' | wc -l)
if [ "$dstate" -gt 0 ]; then
    echo "⚠️ 发现 $dstate 个D状态进程,可能有IO瓶颈"
    ps aux | awk '$8~/D/'
else
    echo "✅ 无D状态进程"
fi

十、容器化进程管理

Docker等容器技术本质上也是进程管理,只是增加了命名空间(Namespace)和控制组(Cgroup)隔离。

# 查看容器进程
docker ps                    # 运行中的容器
docker top container_id      # 容器内进程
docker stats                 # 容器资源使用

# 容器本质上是隔离的进程
# Namespace: PID/NET/MNT/UTS/IPC/USER隔离
# Cgroup: CPU/MEM/IO/网络限制

# 从宿主机看容器进程
ps aux | grep containerd
cat /proc/PID/cgroup         # 查看进程的cgroup归属

十一、性能分析工具

工具功能安装
strace跟踪系统调用apt install strace
ltrace跟踪库函数调用apt install ltrace
perfCPU性能分析apt install linux-perf
iotop磁盘IO监控apt install iotop
latencytop延迟分析apt install latencytop
sysdig系统级深度监控curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash
# strace常用场景
# 跟踪进程系统调用
strace -p PID

# 跟踪特定系统调用
strace -e trace=open,read,write -p PID

# 统计系统调用
strace -c -p PID

# 跟踪网络相关调用
strace -e trace=network -p PID