下面是Day 2 进程管理与调度 的学习内容,包含讲解、演示命令、案例、练习、FAQ,让你从概念到排查问题逐步掌握。
Day 2:Linux 进程管理与调度(Process Management & Scheduler)
目标:掌握 Linux 进程的核心概念、CFS 调度原理、进程优先级及调度策略,学会使用调试工具定位 CPU 性能瓶颈和 lockup 问题。
2.1 进程与线程(Process vs Thread)
了解 Linux 如何管理进程、线程,掌握
task_struct
的关键概念。
1)进程与线程的基本定义
-
进程(Process) 操作系统为正在运行的程序分配的独立资源单元。包括:
- 独立的虚拟内存空间
- 打开的文件描述符表
- 安全上下文(UID、GID、capabilities 等)
-
线程(Thread) 运行在同一进程内的轻量级执行单元,共享虚拟内存空间,但有自己独立的:
- 栈空间
- 程序计数器
- 调度信息
Linux 中的特殊点:
- Linux 不区分严格意义上的"进程"和"线程",两者都由
task_struct
表示。- 内核通过
clone()
系统调用创建子任务,设置不同的CLONE_*
标志位实现线程或进程的效果。
2)进程状态详解
用
ps -eo pid,state,cmd
或top
查看。
状态 | 名称 | 含义 | 常见场景 |
---|---|---|---|
R | Running/可运行 | 当前正在 CPU 上运行,或在运行队列中等待 | 高负载 CPU-bound 任务 |
S | Interruptible Sleep | 可中断睡眠,等待事件或信号唤醒 | 网络 I/O,select /poll 等 |
D | Uninterruptible Sleep | 不可中断睡眠,通常等待 I/O 完成 | 磁盘 I/O,NFS 卡住 |
Z | Zombie | 僵尸进程,进程已退出但父进程未回收 | 父进程编写 Bug |
T | Stopped/Traced | 停止运行,或被调试器挂起 | Ctrl+Z 、ptrace 调试 |
3)实战:查看进程状态
bash
# 启动一个 sleep 进程
sleep 300 &
ps -o pid,ppid,state,cmd -p $!
# 模拟停止进程
kill -STOP $!
ps -o pid,state,cmd -p $!
# 恢复运行
kill -CONT $!
ps -o pid,state,cmd -p $!
4)task_struct 关键字段
每个进程在内核中都由一个 task_struct
结构表示,位于 include/linux/sched.h
。 核心字段:
字段 | 作用 |
---|---|
pid |
进程 ID |
state |
当前进程状态 |
mm |
内存管理信息,指向 mm_struct |
files |
文件描述符表 |
prio / static_prio |
进程优先级 |
se |
CFS 调度实体 |
cgroup |
进程所属的 cgroup |
5)练习题
- 使用
ps
找出系统中所有状态为D
的进程。 - 写一个 Python 脚本创建 5 个线程,用
ps -Lf <PID>
查看线程信息。 - 通过
cat /proc/<PID>/status
找到该进程的PPid
和Threads
字段。
2.2 调度器 (CFS - Completely Fair Scheduler)
Linux 默认使用 CFS(完全公平调度器),目标是 公平分配 CPU 时间。
1)CFS 基本原理
- CFS 将所有可运行进程放入红黑树(RB-tree)。
- 红黑树的 key:
vruntime
(虚拟运行时间),运行时间短的任务优先。 - 当 CPU 空闲时,调度器选择 vruntime 最小 的进程运行。
示意图:
css
[进程 B: vruntime=5]
/ \
[进程 A:2] [进程 C:8]
运行后更新 vruntime,树自动调整,保证所有进程得到公平 CPU 时间。
2)负载相关指标
load average(平均负载)
-
使用
uptime
或sar -q
查看:bashuptime # 输出示例: load average: 3.25, 2.95, 2.88
-
含义 :在给定时间窗口内,处于 R(运行)或 D(不可中断睡眠) 状态的平均进程数。
-
经验判断:
- Load ≈ CPU 核心数:正常。
- Load ≫ CPU 核心数:CPU 或 I/O 瓶颈。
Run Queue(运行队列)
-
查看当前排队进程数:
bashcat /proc/schedstat | head
或
bashsar -q 1 3
3)优先级和 nice 值
类型 | 范围 | 默认值 |
---|---|---|
nice 值 | -20 ~ +19 | 0 |
优先级(PR) | 实时调度:1~99,普通调度:100+nice+20 | 普通进程约 120 |
bash
# 启动一个高优先级任务
nice -n -10 dd if=/dev/zero of=/dev/null &
# 调整优先级
renice -n 5 -p <PID>
4)实时调度(Real-time scheduling)
- SCHED_FIFO:先进先出,无时间片。
- SCHED_RR:轮转,带时间片。
- SCHED_OTHER:普通 CFS 调度。
bash
# 将进程切换为实时调度
sudo chrt -f -p 10 <PID>
chrt -p <PID>
⚠ 风险提示:实时任务可能导致系统卡死,测试环境操作!
2.3 调试与工具
1)top/htop/ps
-
top
:查看实时 CPU 占用。-
重点字段:
%CPU
:单核为 100%NI
:nice 值PR
:优先级S
:进程状态
-
快捷键 :
H
显示线程,P
按 CPU 排序。
-
-
htop
:更直观,支持交互调整优先级。
2)pidstat
bash
# 每秒刷新一次,显示所有进程 CPU 使用率
pidstat 1
# 查看某个 PID 的详细信息
pidstat -p <PID> 1
重点字段:
%usr
:用户态 CPU 占比%system
:内核态 CPU 占比%wait
:等待 I/O 时间
3)perf top
实时分析 函数级 CPU 热点。
bash
sudo perf top
输出示例:
css
20.54% [kernel] [k] copy_user_generic_unrolled
15.12% libc.so.6 [.] memcpy
8.73% my_app [.] process_data
4)ftrace / bpftrace
ftrace 查看调度事件
bash
# 启用调度跟踪
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on
sleep 2
echo 0 > /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/trace
bpftrace 观察调度延迟
bash
sudo bpftrace -e 'tracepoint:sched:sched_switch { printf("%d -> %d\n", args->prev_pid, args->next_pid); }'
5)Soft Lockup / Hard Lockup 排查
症状:系统卡死或响应极慢。
- Soft lockup:CPU 长时间未调度。
- Hard lockup:NMI 中断丢失。
排查路径:
-
查看
/proc/softirqs
、/proc/interrupts
。 -
启用 NMI watchdog:
bashsysctl kernel.nmi_watchdog=1
-
检查
dmesg
输出:bashsoft lockup - CPU#3 stuck for 23s!
Day 2 练习
练习 1:使用 pidstat 分析 CPU 占用
-
启动一个高 CPU 占用程序:
bashyes > /dev/null &
-
运行:
bashpidstat 1
-
找出刚才的高 CPU 占用进程并记下 PID。
练习 2:模拟 soft lockup 并定位
c
// lockup.c
#include <unistd.h>
int main() {
while(1) {} // 无限循环,模拟 lockup
return 0;
}
bash
gcc lockup.c -o lockup
./lockup &
- 检查
dmesg
是否有soft lockup
报告。 - 使用
perf top
查看 CPU 消耗。
练习 3:调整进程优先级
- 启动两个
yes
进程。 - 用
renice
将一个进程的 nice 值调低(-10)。 - 用
top
观察调度变化。
Day 2 FAQ
Q1:load average 一直很高,但 CPU 使用率不高? A:可能是 D 状态进程积压,表示 I/O 阻塞。使用 iotop
、iostat
排查磁盘瓶颈。
Q2:如何判断是软 lockup 还是硬 lockup?
-
dmesg
报错中明确提示:bashsoft lockup - CPU#2 stuck for 22s! hard lockup - CPU#0 NMI watchdog
Q3:nice 值调节对实时进程有效吗? A:不生效。实时任务使用 chrt
控制。
Q4:僵尸进程如何清理? A:杀死父进程,或修改父进程代码正确回收子进程。
Q5:perf
需要特殊权限吗? A:需要 root 或调整 /proc/sys/kernel/perf_event_paranoid
值。
bash
sudo sysctl kernel.perf_event_paranoid=1
Day 2 总结
- 进程管理核心:
task_struct
、进程状态、线程与进程的关系。 - CFS 调度器通过红黑树保证公平性。
- 负载排查核心指标:
load average
、Run Queue、进程优先级。 - 工具组合:
top
→pidstat
→perf top
→ftrace
/bpftrace
。 - Soft/Hard lockup 是严重 CPU 问题,需要 NMI watchdog 配合定位。
下一步(Day 3 预告): 将学习 内存管理与 OOM 问题排查 ,掌握 sar -r
、slabtop
、vmstat
、/proc/meminfo
等工具,并模拟 OOM 崩溃。