5 天学习 Linux Kernel 主要原理 | Day 2:Linux 进程管理与调度

下面是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,cmdtop 查看。

状态 名称 含义 常见场景
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+Zptrace 调试

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)练习题

  1. 使用 ps 找出系统中所有状态为 D 的进程。
  2. 写一个 Python 脚本创建 5 个线程,用 ps -Lf <PID> 查看线程信息。
  3. 通过 cat /proc/<PID>/status 找到该进程的 PPidThreads 字段。

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(平均负载)
  • 使用 uptimesar -q 查看:

    bash 复制代码
    uptime
    # 输出示例: load average: 3.25, 2.95, 2.88
  • 含义 :在给定时间窗口内,处于 R(运行)或 D(不可中断睡眠) 状态的平均进程数。

  • 经验判断:

    • Load ≈ CPU 核心数:正常。
    • Load ≫ CPU 核心数:CPU 或 I/O 瓶颈。
Run Queue(运行队列)
  • 查看当前排队进程数:

    bash 复制代码
    cat /proc/schedstat | head

    bash 复制代码
    sar -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 中断丢失。
排查路径:
  1. 查看 /proc/softirqs/proc/interrupts

  2. 启用 NMI watchdog:

    bash 复制代码
    sysctl kernel.nmi_watchdog=1
  3. 检查 dmesg 输出:

    bash 复制代码
    soft lockup - CPU#3 stuck for 23s!

Day 2 练习


练习 1:使用 pidstat 分析 CPU 占用

  1. 启动一个高 CPU 占用程序:

    bash 复制代码
    yes > /dev/null &
  2. 运行:

    bash 复制代码
    pidstat 1
  3. 找出刚才的高 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:调整进程优先级

  1. 启动两个 yes 进程。
  2. renice 将一个进程的 nice 值调低(-10)。
  3. top 观察调度变化。

Day 2 FAQ


Q1:load average 一直很高,但 CPU 使用率不高? A:可能是 D 状态进程积压,表示 I/O 阻塞。使用 iotopiostat 排查磁盘瓶颈。


Q2:如何判断是软 lockup 还是硬 lockup?

  • dmesg 报错中明确提示:

    bash 复制代码
    soft 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 总结

  1. 进程管理核心:task_struct、进程状态、线程与进程的关系。
  2. CFS 调度器通过红黑树保证公平性。
  3. 负载排查核心指标:load average、Run Queue、进程优先级。
  4. 工具组合:toppidstatperf topftrace/bpftrace
  5. Soft/Hard lockup 是严重 CPU 问题,需要 NMI watchdog 配合定位。

下一步(Day 3 预告): 将学习 内存管理与 OOM 问题排查 ,掌握 sar -rslabtopvmstat/proc/meminfo 等工具,并模拟 OOM 崩溃。

相关推荐
轻松Ai享生活3 小时前
5 天学习 Linux Kernel 主要原理 | Day 1:Linux 内核基础与架构总览
linux
哈喽H4 小时前
centos系统的linux环境不同用户,环境变量不同如何配置?
linux·centos
Doris_LMS5 小时前
在Linux系统中安装Jenkins(保姆级别)
java·linux·jenkins·ci
轻松Ai享生活5 小时前
用户自定义的 systemd unit 文件应该放在哪里?
linux
万添裁5 小时前
1.Linux:命令提示符,history和常用快捷键
linux·运维·服务器
轻松Ai享生活5 小时前
怎么在5天内将Linux systemd学精通
linux
悲伤小伞7 小时前
Linux_网络基础
linux·服务器·c语言·网络
KingRumn7 小时前
Linux ARP老化机制/探测机制/ip neigh使用
linux·网络·tcp/ip
学生董格7 小时前
[嵌入式embed][Qt]Qt5.12+Opencv4.x+Cmake4.x_用Qt编译linux-Opencv库 & 测试
linux·qt·opencv