Linux Scheduler
Linux 5.15 中的调度算法体系结构主要包括几类调度器,分别应用于不同的调度场景,如普通进程调度、实时进程调度、死线程调度、Deadline 任务调度等。以下是 Linux 5.15 中的 主要调度算法和调度类(scheduling classes) :
调度类(Scheduling Classes)
Linux 的调度器采用 多调度类(Modular Scheduler Class)结构,每类代表一种策略,内核根据优先级进行选择:
| 调度类 | 优先级(高→低) | 说明 |
|---|---|---|
SCHED_DEADLINE | 最高 | 实时 Deadline(EDF)调度 |
SCHED_FIFO | 高 | 实时 FIFO |
SCHED_RR | 高 | 实时 Round Robin |
SCHED_NORMAL / SCHED_OTHER | 中 | 普通进程,使用 CFS(完全公平调度器) |
SCHED_BATCH | 中 | 批处理任务,CFS 的变种 |
SCHED_IDLE | 最低 | 空闲进程,系统空闲才运行 |
stop_sched_class | 特殊 | 仅用于迁移/停止 CPU 的专用任务(如 migration 线程) |
主要调度算法
Completely Fair Scheduler(CFS)
- 对应调度策略:SCHED_NORMAL / SCHED_OTHER
- 类名:fair_sched_class
- 核心算法:基于虚拟运行时间(vruntime)构建红黑树(rbtree)
- 目标:所有进程“公平”地获得 CPU 时间
- 特性:
- 支持优先级 nice 值
- 支持组调度(CGroup)
- 支持 NUMA 亲和性优化(Auto NUMA)
Real-Time Scheduler
-
a. SCHED_FIFO(FIFO 实时调度器)
- 类名:rt_sched_class
- 无时间片,先到先服务,不会被同优先级线程抢占
-
b. SCHED_RR(Round Robin 实时调度器)
- 类名:rt_sched_class
- 固定时间片轮转,同优先级任务轮流运行
SCHED_DEADLINE(Deadline 调度器)
- 类名:dl_sched_class
- 实现 Earliest Deadline First (EDF) + Constant Bandwidth Server (CBS)
- 支持实时性强的周期性任务
- 用户指定:
- runtime: 最长运行时间
- deadline: 截止时间
- period: 周期时间
sched_attr {
__u64 sched_runtime;
__u64 sched_deadline;
__u64 sched_period;
}
SCHED_BATCH
- 类名:fair_sched_class(复用 CFS)
- 不考虑交互性,仅用于 CPU 密集型作业
- 延迟调度,降低优先级影响前台进程
SCHED_IDLE
- 类名:idle_sched_class
- 仅在 CPU 完全空闲时运行
- 对应如 idle thread、低优先后台任务
特殊调度器(辅助类)
stop_sched_class
- 用于如 migration/x、kstop 等特殊线程
- 不参与普通调度,优先级最高
- 运行于调度器需要强制控制 CPU 的情形(如 CPU hotplug)
关核心数据结构
struct task_struct:每个进程的描述符,包含 policy 字段定义调度策略struct sched_class:调度类的定义,包含调度操作接口struct cfs_rq / rt_rq / dl_rq:每种调度器在 runqueue 中的运行队列
总结:Linux 5.15 支持的调度策略及映射表
| 策略常量 | 用户命令 | 内核类名 | 算法 | 应用场景 |
|---|---|---|---|---|
SCHED_OTHER | 默认 | fair_sched_class | CFS | 普通进程 |
SCHED_BATCH | chrt -b | fair_sched_class | CFS 批处理模式 | 批处理任务 |
SCHED_IDLE | chrt -i | idle_sched_class | 最低优先级 | 后台或空闲任务 |
SCHED_FIFO | chrt -f | rt_sched_class | FIFO | 实时控制任务 |
SCHED_RR | chrt -r | rt_sched_class | Round Robin | 实时任务 |
SCHED_DEADLINE | chrt -d | dl_sched_class | EDF + CBS | 高精度实时系统 |
混合使用 Linux 的调度算法
Linux 的调度算法是混合使用的,这是其调度器设计的核心特点之一。Linux 使用了一种称为 多调度类架构(Multi-class Scheduling Architecture) 的机制,允许不同类型的任务(普通、实时、Deadline 等)被分配给不同的调度类(sched_class),并在内核中分层调度,形成一个混合调度系统。
混合使用的本质机制
Linux 调度器的行为:
- 每个任务都有自己的调度策略(如 SCHED_FIFO, SCHED_OTHER, SCHED_DEADLINE 等)
- 不同策略的任务属于不同的调度类(如 dl_sched_class, rt_sched_class, fair_sched_class, idle_sched_class)
- 调度器按照调度类的优先级顺序,逐层查找可运行任务
简单来说:Linux 会从最高优先级的调度类往下查找,直到找到可运行任务为止。
调度类优先级从高到低如下:
dl_sched_class (SCHED_DEADLINE)
↑
rt_sched_class (SCHED_FIFO / SCHED_RR)
↑
fair_sched_class (SCHED_OTHER / SCHED_BATCH)
↑
idle_sched_class (SCHED_IDLE)
混合调度实际例子
场景:系统中存在三种进程
- 实时任务(SCHED_FIFO)
- 普通任务(SCHED_OTHER)
- 后台低优先级任务(SCHED_IDLE)
内核调度流程如下:
- 首先查看 dl_sched_class(是否有 SCHED_DEADLINE 任务)
- 没有 deadline 任务,则查看 rt_sched_class(是否有 SCHED_FIFO / RR)
- 没有实时任务,则执行 fair_sched_class(普通任务使用 CFS)
- 只有当前三类都无任务可运行,才会调度 idle_sched_class(空闲任务)
因此,如果你在系统中创建一个 SCHED_FIFO 的实时任务,即使有大量普通任务,实时任务仍会优先被调度。
调度类之间的协作和切换
- 不同调度类之间互相独立实现自己的调度算法(如 CFS 使用红黑树,RT 使用优先级链表)
- 由 pick_next_task() 在调度切换时决定当前最合适的任务
- 各调度类之间通过函数指针链表串联,按优先级依次执行
- 所有调度类的接口都定义在 struct sched_class 中,包括:
struct sched_class {
struct sched_class *next;
void (*enqueue_task)(...);
struct task_struct *(*pick_next_task)(...);
...
};
Linux 调度算法混合使用
| 方面 | 说明 |
|---|---|
| 是否混合 | 是的,调度类之间分层级、按优先级混合调度 |
| 实现方式 | 各调度类实现自己的调度算法,通过统一接口连接起来 |
| 决策顺序 | DEADLINE → RT → CFS → IDLE,逐层优先级查找可运行任务 |
| 混合效果 | 实现灵活的系统行为,既支持实时性,又保障普通进程公平运行 |
2038

被折叠的 条评论
为什么被折叠?



