进程管理 进程基础概念 进程 (Process) 是程序的一次执行实例,是系统进行资源分配和调度的基本单位。每个进程都有独立的内存空间和系统资源。
进程与程序的区别
概念
定义
特点
程序 (Program)
存储在磁盘上的可执行文件
静态的、永久的
进程 (Process)
程序的运行实例
动态的、临时的
比喻 :
进程的类型
按交互方式分类
前台进程 (Foreground)
后台进程 (Background)
按启动方式分类
交互式进程
由用户从终端启动 如:bash、vim、firefox 批处理进程
与终端无关,提交到作业队列 如:at、batch 启动的任务 守护进程 (Daemon)
系统启动时自动运行 一直在后台运行 通常以 ‘d’ 结尾命名 如:sshd、httpd、crond
按进程关系分类
父进程 (Parent Process)
子进程 (Child Process)
孤儿进程 (Orphan Process)
僵尸进程 (Zombie Process)
进程标识 每个进程都有唯一的标识符:
标识符
说明
获取方式
PID (Process ID)
进程唯一标识
echo $$
PPID (Parent PID)
父进程 ID
echo $PPID
PGID (Process Group ID)
进程组 ID
ps -o pgid= -p <pid>
SID (Session ID)
会话 ID
ps -o sid= -p <pid>
UID (User ID)
进程所有者 ID
ps -o uid= -p <pid>
EUID (Effective UID)
有效用户 ID
ps -o euid= -p <pid>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 echo $$echo $PPID ps -f -p $$ ps -o pid,ppid,cmd -p $$ pstree pstree -p pstree -u
查看进程 ps 命令 ps (Process Status) 是最基础的进程查看命令。
1 2 3 4 5 6 7 8 9 10 11 12 ps ps aux ps -ef ps auxf ps -ejH
BSD 风格 (ps aux) :
字段
含义
说明
USER
进程所有者
启动进程的用户
PID
进程 ID
唯一标识符
%CPU
CPU 使用率
进程占用的 CPU 百分比
%MEM
内存使用率
进程占用的物理内存百分比
VSZ
虚拟内存大小
Virtual Memory Size (KB)
RSS
常驻内存大小
Resident Set Size (KB)
TTY
控制终端
进程关联的终端
STAT
进程状态
见下方详细说明
START
启动时间
进程开始运行的时间
TIME
CPU 时间
进程累计使用的 CPU 时间
COMMAND
命令
启动进程的命令及参数
System V 风格 (ps -ef) :
字段
含义
UID
用户 ID
PID
进程 ID
PPID
父进程 ID
C
CPU 使用率
STIME
开始时间
TTY
终端
TIME
CPU 时间
CMD
命令
状态码
含义
说明
R
Running / Runnable
正在运行或在运行队列中等待
S
Interruptible Sleep
可中断睡眠,等待某个条件
D
Uninterruptible Sleep
不可中断睡眠,通常在进行 I/O
T
Stopped
被信号停止(如 Ctrl+Z)
t
Tracing Stop
被调试器跟踪停止
Z
Zombie
僵尸进程,已终止但未被回收
X
Dead
死亡进程(不应该看到)
附加状态标志 :
标志
含义
<
高优先级
N
低优先级
L
有锁定页面(用于实时)
s
会话领导者
l
多线程
+
前台进程组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ps -eo pid,ppid,cmd,%mem,%cpu --sort =-%cpu | head ps -u username ps aux | grep ^username ps aux --sort =-%mem | head -10 ps aux --sort =-%cpu | head -10 ps axjf ps -eo pid,ppid,cmd | sort -n | head ps -eLf ps aux -L ps aux | grep nginx | grep -v grep ps aux | awk '{print $11}' | sort | uniq -c | sort -rn
top 命令 top 提供动态的进程监控视图。
top 命令详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 top top -d 1 top -u username top -p PID1,PID2,PID3 top -b -n 1
交互命令 (在 top 运行时按):
按键 功能 ? / h 帮助 q 退出 Space 立即刷新 k 终止进程(输入 PID) r 修改进程优先级(renice) c 切换显示完整命令 M 按内存使用排序 P 按 CPU 使用排序 T 按运行时间排序 N 按 PID 排序 u 过滤特定用户 n 设置显示进程数 i 切换显示空闲进程 V 树状显示 t 切换 CPU 状态显示 m 切换内存状态显示 1 显示每个 CPU 核心 W 保存配置到 ~/.toprc
输出字段说明 :
1 2 3 4 5 6 7 8 9 top - 14:30:25 up 3 days, 2:15, 2 users, load average: 0.52, 0.58, 0.59 Tasks: 235 total, 1 running, 234 sleeping, 0 stopped, 0 zombie %Cpu(s): 5.2 us, 2.1 sy, 0.0 ni, 92.3 id, 0.2 wa, 0.0 hi, 0.2 si, 0.0 st KiB Mem : 8167844 total, 1234567 free, 3456789 used, 3476488 buff/cache KiB Swap: 2097148 total, 2097148 free, 0 used. 4321098 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1234 alice 20 0 123456 78901 12345 S 5.2 1.0 2:34.56 firefox ...
行/字段 说明 第1行 系统时间和运行时间 14:30:25 当前时间 up 3 days, 2:15 系统已运行时间 2 users 当前登录用户数 load average 1/5/15分钟平均负载 第2行 任务统计 235 total 总进程数 1 running 运行中 234 sleeping 睡眠中 0 stopped 已停止 0 zombie 僵尸进程 第3行 CPU 使用率 us 用户空间 sy 系统空间 ni nice 调整后的用户空间 id 空闲 wa I/O 等待 hi 硬中断 si 软中断 st 被虚拟机偷走的时间 第4-5行 内存和交换空间 进程列表 各进程详情
进程控制 前台与后台进程 1 2 3 4 5 6 7 8 9 10 11 12 13 long_running_command & sleep 60 &./backup_script.sh > output.log 2>&1 & jobs [1] + running sleep 60 [2] - suspended vim file.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Ctrl + Z jobs jobs -l jobs -p fg %1 fg %vim fg %% fg %+ fg %- bg %1bg %2kill %1wait %1echo $?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 nohup command &nohup ./script.sh > output.log 2>&1 &nohup python3 server.py &long_running_task & disown disown %1(long_running_task &)
信号 (Signals) 信号是进程间通信的一种机制,用于通知进程发生了某个事件。
常用信号
信号 数值 名称 默认动作 说明 1 SIGHUP Hangup 终止 终端挂起或控制进程结束 2 SIGINT Interrupt 终止 来自键盘的中断(Ctrl+C) 3 SIGQUIT Quit 核心转储 来自键盘的退出(Ctrl+\) 6 SIGABRT Abort 核心转储 调用 abort() 产生 9 SIGKILL Kill 终止 强制终止,不可捕获或忽略 15 SIGTERM Terminate 终止 正常终止信号(默认) 18 SIGCONT Continue 继续 继续执行暂停的进程 19 SIGSTOP Stop 暂停 暂停进程执行(Ctrl+Z) 20 SIGTSTP TTY Stop 暂停 终端停止信号
关键信号详解 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
发送信号的方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 kill PID kill -9 PID kill -SIGKILL PIDkill -KILL PIDkill PID1 PID2 PID3killall process_name killall -9 process_name killall -u username process_name pkill process_name pkill -f "full command line" pkill -u username Ctrl + C Ctrl + Z Ctrl + \
捕获信号示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #!/bin/bash cleanup () { echo "收到终止信号,正在清理..." rm -f /tmp/my_script_temp_$$ echo "清理完成,退出" exit 0 } trap cleanup SIGTERM SIGINT SIGHUPecho "程序运行中... (PID: $$)" echo "临时文件: /tmp/my_script_temp_$$" touch /tmp/my_script_temp_$$while true ; do echo "工作中... $(date) " sleep 5 done
系统监控工具 htop - 交互式进程查看器 1 2 3 4 5 6 sudo apt-get install htop sudo yum install htop htop
交互按键 :
按键
功能
F1 / ?
帮助
F2 / S
设置
F3 / /
搜索进程
F4 / \\
过滤器
F5 / t
树状显示
F6
选择排序字段
F7 / [
降低进程优先级 (nice +)
F8 / ]
提高进程优先级 (nice -)
F9 / k
杀死进程
F10 / q
退出
u
按用户过滤
M
按内存排序
P
按 CPU 排序
T
按时间排序
I
反转排序
l
显示/隐藏线程
vmstat - 虚拟内存统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 vmstat vmstat 1 vmstat 1 10 vmstat -s vmstat -a vmstat -d vmstat -D vmstat -p /dev/sda1 vmstat -f procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 123456 78901 456789 0 0 10 20 100 200 5 2 93 0 0 procs: r: 运行队列中的进程数 b: 等待 I/O 的进程数 memory: swpd: 使用的虚拟内存 (KB) free: 空闲内存 (KB) buff: 用作缓冲区的内存 (KB) cache: 用作缓存的内存 (KB) swap: si: 从磁盘交换入内存 (KB/s) so: 从内存交换出到磁盘 (KB/s) io: bi: 从块设备读取 (blocks/s) bo: 写入块设备 (blocks/s) system: in : 中断数 (/s) cs: 上下文切换数 (/s) cpu: us: 用户空间时间 (%) sy: 系统空间时间 (%) id : 空闲时间 (%) wa: I/O 等待时间 (%) st: 被虚拟机偷走的时间 (%)
iostat - I/O 统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 sudo apt-get install sysstatiostat iostat 1 iostat 1 10 iostat -c iostat -d iostat -x iostat -m iostat -k iostat -p sda iostat -p ALL Linux 5.4.0-65-generic (hostname) 01/15/2024 _x86_64_ (4 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 5.23 0.01 2.15 0.50 0.00 92.11 Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd sda 12.34 45.67 89.01 0.00 1234567 2345678 0 sdb 0.12 1.23 0.45 0.00 12345 4567 0 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 2.34 10.00 45.67 89.01 0.12 3.45 4.89 25.67 3.45 8.90 0.12 19.52 8.90 0.80 0.98 avg-cpu: %user - 用户空间程序使用的 CPU 百分比 %nice - 带有 nice 优先级的用户程序 %system - 内核空间使用的 CPU 百分比 %iowait - 等待 I/O 完成的时间百分比 %steal - 虚拟机管理程序占用的时间 %idle - CPU 空闲时间百分比 Device: tps - 每秒传输次数 (I/O 请求数) kB_read/s - 每秒读取的数据量 (KB) kB_wrtn/s - 每秒写入的数据量 (KB) kB_dscd/s - 每秒丢弃的数据量 (KB) 扩展统计: r/s - 每秒读取请求数 w/s - 每秒写入请求数 rkB/s - 每秒读取 KB 数 wkB/s - 每秒写入 KB 数 rrqm/s - 每秒合并的读取请求 wrqm/s - 每秒合并的写入请求 %rrqm - 读取请求合并百分比 %wrqm - 写入请求合并百分比 r_await - 读取请求平均等待时间 (ms) w_await - 写入请求平均等待时间 (ms) aqu-sz - 平均队列长度 rareq-sz - 平均读取请求大小 (KB) wareq-sz - 平均写入请求大小 (KB) svctm - 平均服务时间 (ms) %util - 设备带宽利用率
其他监控工具 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 sudo apt-get install dstatdstat dstat -y dstat --full dstat -cdngy 1 dstat --output report.csv 1 60 sudo apt-get install sysstatsar -u 1 10 sar -r 1 10 sar -d 1 10 sar -n DEV 1 10 sar -q 1 10 sar -A sar -f /var/log/sysstat/sa15 sudo apt-get install nethogssudo nethogs sudo nethogs eth0 sudo apt-get install iotopsudo iotop sudo iotop -o sudo iotop -b -n 5 sudo apt-get install sysstatpidstat pidstat -r pidstat -d pidstat -w pidstat -u 1 5 pidstat -t -p PID time slabtopsudo apt-get install linux-tools-common linux-tools-genericsudo perf top sudo perf stat -a sleep 5 sudo perf record -a -g -- sleep 30 sudo perf report
进程优先级 nice 和 renice 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 nice -n 10 long_running_tasknice --10 command renice -n 5 -p PID renice -n 5 -u username renice -n 5 -g groupname ps -eo pid,ni,cmd | grep firefox pidstat -u -p PID chrt -f -p 99 PID chrt -r -p 50 PID chrt -o -p 0 PID chrt -p PID
实践练习 练习:找出最耗资源的进程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/bin/bash echo "=== CPU 使用率最高的 10 个进程 ===" ps aux --sort =-%cpu | head -11 | tail -10 | awk '{printf "%-10s %6s %5s %5s %s\n", $1, $2, $3, $4, $11}' echo "" echo "=== 内存使用率最高的 10 个进程 ===" ps aux --sort =-%mem | head -11 | tail -10 | awk '{printf "%-10s %6s %5s %5s %s\n", $1, $2, $3, $4, $11}' echo "" echo "=== 运行时间最长的 10 个进程 ===" ps -eo user,pid,etime,cmd --sort =etime | tail -10 echo "" echo "=== 当前用户的进程统计 ===" echo "进程总数: $(ps -u $USER -o pid= | wc -l) " echo "CPU 使用: $(ps aux | awk -v user=$USER '$1==user {sum+=$3} END {print sum "%" }') " echo "内存使用: $(ps aux | awk -v user=$USER '$1==user {sum+=$4} END {print sum "%" }') "
练习:监控系统并自动处理高负载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #!/bin/bash LOG_FILE="/var/log/system_monitor.log" CPU_THRESHOLD=80 MEM_THRESHOLD=90 LOAD_THRESHOLD=$(nproc ) log_message () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " | tee -a $LOG_FILE } get_system_info () { CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1) MEM_USAGE=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}' ) LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',' ) DISK_USAGE=$(df -h / | tail -1 | awk '{print $5}' | tr -d '%' ) } kill_heavy_processes () { log_message "WARNING: High CPU usage detected ($CPU_USAGE %). Taking action..." HEAVY_PIDS=$(ps aux --sort =-%cpu | grep -v "^root\|^USER" | head -5 | awk '{print $2}' ) for PID in $HEAVY_PIDS ; do PROCESS_INFO=$(ps -p $PID -o pid,ppid,cmd,%cpu --no-headers 2>/dev/null) if [ -n "$PROCESS_INFO " ]; then log_message "Killing process: $PROCESS_INFO " kill -TERM $PID 2>/dev/null sleep 2 if kill -0 $PID 2>/dev/null; then log_message "Process $PID still running, using SIGKILL" kill -KILL $PID 2>/dev/null fi fi done } clean_memory () { log_message "WARNING: High memory usage detected ($MEM_USAGE %). Cleaning caches..." if [ $(id -u) -eq 0 ]; then sync echo 3 > /proc/sys/vm/drop_caches log_message "Memory caches cleaned" else log_message "WARNING: Root privileges required to clean memory caches" fi } main () { log_message "System monitor started (PID: $$)" log_message "Thresholds - CPU: ${CPU_THRESHOLD} %, Memory: ${MEM_THRESHOLD} %, Load: ${LOAD_THRESHOLD} " while true ; do get_system_info log_message "Status - CPU: ${CPU_USAGE} %, Memory: ${MEM_USAGE} %, Load: ${LOAD_AVG} , Disk: ${DISK_USAGE} %" if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD " | bc -l) )); then kill_heavy_processes fi if (( $(echo "$MEM_USAGE > $MEM_THRESHOLD " | bc -l) )); then clean_memory fi sleep 60 done } trap 'log_message "Monitor stopped"; exit 0' SIGTERM SIGINTmain
延伸阅读