Linux 调度类(sched_class)

Linux 调度类(sched_class)

总览与优先级顺序

Linux 内核把不同调度策略的实现抽象为若干调度类(sched_class),系统按固定顺序遍历这些类来选择下一个运行任务。常见的类及顺序是:

  • stop_sched_class(最高优先级,用于内核"停止/停机"场景)
  • dl_sched_class (SCHED_DEADLINE,基于 EDF/CBS 的实时到期调度)
  • rt_sched_class (SCHED_FIFO / SCHED_RR,基于优先级的实时调度)
  • fair_sched_class (CFS,普通任务/批处理的公平调度)
  • idle_sched_class(最低优先级,CPU 空闲线程)

内核中对应的声明示例:

c 复制代码
extern const struct sched_class stop_sched_class;
extern const struct sched_class dl_sched_class;
extern const struct sched_class rt_sched_class;
extern const struct sched_class fair_sched_class;
extern const struct sched_class idle_sched_class;

sched_class 抽象(接口与职责)

每个调度类通过 struct sched_class 提供一组回调函数,常见接口包括:

enqueue_task / dequeue_task:把任务放入/移出该类的就绪结构。

pick_next_task:从该类中选择下一个要运行的 task_struct*(scheduler 调度时首要调用)。

task_tick:tick 时类特有的处理(如 RR 换位、CFS 更新 vruntime)。

get_rr_interval:只对带时间片的实时轮转(SCHED_RR)有意义。

balance / select_task_rq / migrate_task_rq / task_woken / set_cpus_allowed:仅在 SMP 下由类实现与负载均衡和迁移相关的策略。

switched_from / switched_to / prio_changed:切换或优先级变化时的处理(注意 switched_from 可能释放 rq->lock,pair 是由 p->pi_lock 串行化)。

uclamp_enabled(条件编译项):类是否支持 uclamp。

enqueue_task / dequeue_task:把任务放入/移出该类的就绪结构。

pick_next_task:从该类中选择下一个要运行的 task_struct*(scheduler 调度时首要调用)。

task_tick:tick 时类特有的处理(如 RR 换位、CFS 更新 vruntime)。

get_rr_interval:只对带时间片的实时轮转(SCHED_RR)有意义。

balance / select_task_rq / migrate_task_rq / task_woken / set_cpus_allowed:仅在 SMP 下由类实现与负载均衡和迁移相关的策略。

switched_from / switched_to / prio_changed:切换或优先级变化时的处理(注意 switched_from 可能释放 rq->lock,pair 是由 p->pi_lock 串行化)。

uclamp_enabled(条件编译项):类是否支持 uclamp。

各调度类详解

1) stop_sched_class

  • 用途:处理内核的 stop/停止样例(如 stop_machine、CPU 热插拔相关的短期"阻塞/停止"任务)。
  • 特点:优先级最高,短期任务,确保内核关键工作能抢占其他用户任务。

2) dl_sched_class(SCHED_DEADLINE)

  • 用途:实现 SCHED_DEADLINE 策略,支持实时任务的最早截止优先(EDF)与带宽保护(Capacity / CBS)。
  • 数据结构:dl_entity、dl_rq,记录 runtime、deadline、period。
  • 行为:选取最早 deadline 的可运行任务;调度时需保证任务不超出其 runtime(会拒绝或回退调度申请以保护其它任务)。
  • 适用场景:严格实时任务、需要签订带宽的场景(多媒体、控制系统等)。

3) rt_sched_class(SCHED_FIFO / SCHED_RR)

  • 用途:传统实时策略,基于静态优先级(0--99)。SCHED_FIFO:先到先运行直到阻塞/自愿让出;SCHED_RR:同优先级轮转时间片。
  • 数据结构:按优先级分队列 + 优先级位图(bitmap)以快速找到最高优先级任务。
  • 特点:优先级高于 CFS,被 RT 任务占满时会阻塞普通任务;对响应性要求高,但可导致优先级反转问题(需使用优先级继承等机制)。
  • 调度与抢占:RT 任务一旦就绪通常会抢占低优先级任务。rr 使用 timeslice(sched_rr_timeslice_ms)进行轮转。

4) fair_sched_class(CFS:完全公平调度器)

  • 用途:Linux 默认普通进程/线程的调度(SCHED_OTHER、SCHED_BATCH 等)。
  • 核心思想:以虚拟运行时间(vruntime)衡量"占用份额",把 CPU 时间尽可能公平地分配给 runnable 实体。
  • 关键数据结构:
    • struct sched_entity:表示可调度实体(任务或任务组)。
    • struct cfs_rq:维护红黑树(rb_tree)按 vruntime 排序;跟踪 min_vruntime、load weight、runnable sum。
  • 时钟与片段:通过 sched_latency、min_granularity、nice 权重影响时间片大小(较重的进程获得更多 CPU 时间)。
  • 负载均衡:有复杂的跨 CPU 平衡策略(pull/push、负载递归域 balance_domains),支持 cgroup/V2 的层级公平调度(hierarchical scheduling)。
  • 优点:整体公平与可伸缩;缺点:复杂度高,调优点多(如响应短任务的最小粒度)。

5) idle_sched_class

  • 用途:当无其他任务可运行时,运行每个 CPU 的 idle 线程。
  • 特点:最低优先级,通常进入节能/空闲循环。

调度决策流程要点(高层)

  1. 就绪/唤醒:唤醒时会调用相应调度类的 enqueue_task,并可能触发 check_preempt_curr 来判断是否立刻抢占。
  2. 选择任务:调度器(pick_next_task_fair 等)会按调度类顺序调用每个类的 pick_next_task,第一类返回非 NULL 的任务即被选中(即高优先级类优先)。
  3. 切换与时钟片:调用 put_prev_task / set_curr_task / task_tick 等维护数据与切片逻辑。
  4. 迁移/均衡:负载均衡逻辑会在必要时移动任务或调整 runqueue(不同类有不同的均衡策略)。

策略与系统调用

  • 政策设置:sched_setscheduler(SCHED_FIFO / SCHED_RR / SCHED_OTHER 等)、sched_setattr(包含 SCHED_DEADLINE 参数)。
  • 查看/调试:/proc//sched、/proc/sched_debug、chrt、schedtool;可以用 ps -o pid,comm,policy,rtprio。
相关推荐
无限进步_10 小时前
【Linux】Makefile:让编译自动化
linux·运维·自动化
猫头虎10 小时前
【Trea】Trea国内版|国际版|海外版下载|Mac版|Windows版|Linux下载配置教程
linux·人工智能·windows·macos·aigc·ai编程·agi
Jinkxs10 小时前
LoadBalancer- 简单限流策略:Nginx 基于连接 / 请求的限流实现
java·运维·nginx
崇山峻岭之间10 小时前
单片机串口实验
单片机·嵌入式硬件
爱的si念10 小时前
Zephyr 在 Nucleo G474RE 的完整编译与模块提取指南
stm32·单片机·嵌入式硬件
流浪00110 小时前
告别静态打印:Linux C 实现实时刷新进度条
linux·运维·c语言
qq_1969761710 小时前
硬核教程:用Gemini境像站构建端到端自动化办公工作流,告别重复操作(国内免费镜像实测)
运维·自动化
小此方10 小时前
Re:Linux系统篇(二十)进程篇·五:深入理解 Linux 进程优先级:从底层逻辑到实战修改
linux·运维·服务器
路溪非溪10 小时前
Linux下物理总线驱动模型之SDIO驱动框架
linux·驱动开发
深圳市九鼎创展科技10 小时前
九鼎创展 X7110 开发板(JH7110):国产 RISC-V 多媒体平台全解析
大数据·linux·人工智能·嵌入式硬件·ubuntu·risc-v