引言
进程调度是操作系统的核心组件,它决定了哪个进程在何时获得CPU执行时间。Linux内核的调度器经历了从O(n)调度器到O(1)调度器,再到如今广泛使用的CFS(完全公平调度器),以及Linux 6.6引入的新一代EEVDF(Earliest Eligible Virtual Deadline First)算法的演进过程。本文将深入剖析这些调度器的工作原理、数据结构和性能特征。
一、CFS完全公平调度器核心原理
1.1 设计理念
CFS(Completely Fair Scheduling)引入了革命性的设计理念:"完全公平"。传统调度器以时间片轮转为基础,CFS则采用了一种更加精确的公平模型:
- 虚拟运行时间(vruntime):每个进程维护一个虚拟运行时间计数器,记录该进程在CPU上经过"归一化"的执行时间
- 红黑树调度队列:所有可运行进程按vruntime排序存储在红黑树中
- "理想多任务处理器"模型:如果CPU能够同时在所有进程间完美切换,则每个进程获得的CPU时间与其权重成正比
1.2 vruntime 计算
vruntime的更新公式是CFS的核心:
delta_vruntime = delta_exec × (NICE_0_LOAD / weight)
其中:
delta_exec:实际执行时间NICE_0_LOAD:nice值为0时的权重(1024)weight:进程的实际权重
这意味着高权重(高优先级)进程的vruntime增长更慢,从而获得更多的实际CPU时间。
1.3 红黑树调度队列
CFS使用红黑树(rbtree)作为调度队列的核心数据结构:
- 键值为进程的vruntime
- 最左侧节点(最小vruntime)就是下一个要调度的进程
- 插入和查找操作的时间复杂度为O(log n)
- 每个CPU维护自己的运行队列(cfs_rq)
1.4 调度延迟与最小粒度
CFS通过两个关键参数平衡响应速度和上下文切换开销:
- sysctl_sched_latency(默认6ms):目标调度延迟,即每个可运行进程在此时间内至少被调度一次
- sysctl_sched_min_granularity(默认0.75ms):最小执行时间,防止进程被抢占过快导致的缓存抖动
二、CFS 调度算法深度分析
2.1 进程选择
CFS总是选择vruntime最小的进程执行:
pick_next_task_fair() -> pick_next_entity()
-> rb_first(

发表评论 取消回复