当前位置: 首页 > news >正文

Linux调度分析(4)调度core之简介

调度Core是调度的核心框架,它负载调度整个过程的框架,而不同的调度类负责填充调度core的回调接口,做最终不同调度类的调度决定。

调度类分类

目前的调度类从优先级依次下降为:

  1. stop调度类
    最高优先级调度类,不会被抢占。通常task migration等线程使用该调度类
  2. deadline调度类
    实时调度类,用户态可以通过setscheduler将某个线程调度策略设置为SCHED_DEADLINE。优先级小于0。
  3. realtime调度类
    Rt调度类的线程优先级[-1, 99],其调度策略分为SCHED_FIFO和SCHED_RR
  4. fair调度类
    Fair调度类的线程优先级[100, 139], 其调度策略分为SCHED_NORMAL
  5. ext调度类
    ext调度类的线程优先级[100, 139], 其调度策略分为SCHED_EXT
  6. idle调度类
    最低优先级调度类,idle线程使用。只有在没有其他线程可调用时才会调用idle线程。Idle线程优先级为140。

设置调度类的时机

不同线程的调度类被设置的时机不一样:

  • stop/idle调度类时在内核初始化过程中静态设置的
  • 可以通过sched_setscheduler()设置线程的调度策略
  • 子线程继承父线程的优先级,在sched_fork()根据prio范围设置rt/fair/ext调度类

调度类回调函数

调度core为调度的框架,负责提供用户态/内核态的框架,包含唤醒过程、调度过程、时钟处理、IDLE过程、负载跟踪和负载均衡等。但每个调度类的具体实现即真正的调度决定则在具体调度中的回调函数中实现。
具体的调度类填充由DEFINE_SCHED_CLASS()来定义。
void (*enqueue_task)(struct rq *rq, struct task_struct *p, int flags)
将task放入到运行队列中
void (*dequeue_task)(struct rq *rq, struct task_struct *p, int flags)
将task出队列
void (*yield_task)( )(struct rq *rq)
放弃当前运行队列上的task的运行
void (*yield_to_task)( struct rq *rq, struct task_struct *p)
判断是否当前CPU给p运行
void (*wakeup_preempt)( struct rq *rq, struct task_struct *prev, int flags)
如果有必要,抢占当前的task
int (*balance)( struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
在选择下一个task运行之前,某些情况(如使能SCX)会调用balance做负载均衡
Struct task_struct *(*pick_task)( struct rq *rq)
Struct task_struct (pick_next_task)( struct rq *rq, struct task_struct *prev)
选择下一个task运行,两者实现其中一个
Void (*put_prev_task)( struct rq *rq, struct task_struct *p, struct task_struct *next)
Void (*set_next_task)( struct rq *rq, struct task_struct *p, bool first)
设置cfs_rq->curr,负载计算
Int (*select_task_rq)(struct task_struct *p, int task_cpu, int flags)
为task选择CPU运行
Void (*migrate_task_rq)(struct task_struct *p, int new_cpu)
将task迁移到新的CPU上
Void (*task_woken)(struct rq *this_rq, struct task_struct *task)
Void (*set_cpus_allowed)( struct task_struct *p, struct affinity_context *ctx)
为task设置亲和性
Void (*rq_online)(struct rq *rq)
Void (*rq_offline)( struct rq *rq)
在CPU online/offline时被调用
Struct rq *(*find_lock_rq)(struct task_struct *p, struct rq *rq)
在CPU stop时被调用,仅RT和DL调度类被填充,用于寻找最闲的rq
Void (*task_tick)( struct rq *this_rq, struct task_struct *task, int queued)
调度周期性时钟达到时被调用,周期性更新负载、重新调度等
Void (*task_fork)(struct task_struct *p)
在fork时被调用,仅CFS调度类被填充,设置允许最大capacity
Void (*task_dead)(struct task_struct *p)
在完成context_switch后若状态为DEAD时被调用,仅CFS调度类被填充
Void (*switching_to)(struct rq *this_rq, struct task_struct *task)
Void (*switched_from)(struct rq *this_rq, struct task_struct *task)
Void (*switched_to)(struct rq *this_rq, struct task_struct *task)
用于rt_mutex实现优先级继承逻辑,在task优先级发生变化时被调用。若task的调度类发生变化,在dequeue出来后设置新的调度类后调用switching_to(),在enqueue后先调用switched_from将原来task disable,再调用switched_to
Void (*reweight_task)( struct rq *this_rq, struct task_struct *task, const struct load_weight *w)
在设置nice或设置调度系统调用或Init_task初始化时被调用,用于设置负载权重
Void (*prio_changed)(struct rq *this_rq, struct task_struct *task, int oldprio)
在设置task优先级不改变调度类时被调用
Void (*update_curr)(struct rq *rq)
系统调用getrusage用于获取当前进程的资源情况。该接口在统计Cpu time时会被用来更新当前task的runtime统计。
Void (*task_change_group)(struct task_struct *p)
在不同group中移动时被调用
Void (*task_is_throttled)(struct task_struct *p, int cpu)
判断task是否throttled。Throttled task指的是RQ或cgroup的配额runtime用完,暂时禁止被运行知道bandwidth重新获取。

调度涉及的过程概括

  1. 旧的线程(prev线程)在调度时机会主动或被动让出CPU,这个过程成为调度过程
  2. 在prev线程让出CPU后,从CPU的runqueue中按调度策略选择其他的线程new线程运行,这个过程成为调度切换过程
  3. 在prev线程满足资源条件或其他条件时被其他线程唤醒,选择合适的CPU,并加入到对应的队列中,这个过程成为选核或唤醒过程
  4. 选核时可能会根据各个CPU的繁忙情况选择合适的CPU,这时就要求系统能够跟踪负载。当不同CPU上负载差距比较大,在何时的时机会进行负载均衡
  5. 在CPU上没有其他task运行时,CPU会进入idle状态,运行idle线程,idle有不同的级别,进入idle并选择哪个idle级别,这个过程为Idle过程
  6. CPU支持不同的频点,如何选择不同的频率并调频,这个过程为Cpufreq过程
  7. 在特定调度时机,包括主动时机和被动时机:主动调度时机比如线程主动调用schedule()或sleep()或cond_resched()等让出CPU;被动时机比如在系统调用从内核态返回用户态,在PREEMPT抢占内核在中断结束时

image

http://www.jsqmd.com/news/204563/

相关文章:

  • Allegro许可证使用情况可视化监控面板设计
  • 20251210
  • Markdown输出格式优化:让VibeThinker生成更易读的回答
  • 20251117
  • 实现UG/NX数字化设计与制造资源最优配置战略
  • 20251211
  • 速率限制策略:防止单个用户过度占用资源
  • Twitter/X发文预告:用英文介绍VibeThinker核心亮点
  • 2026年轻量化无人机建图识别的关键战役,谁在引领变革? - 品牌2025
  • 思维链(CoT)增强技巧:引导VibeThinker输出中间推理
  • 【2026年】【国内】GEO优化源码可商用性测评TOP4 - 品牌推荐官优选
  • 多版本EB-Cable环境许可证兼容性管理方案
  • 20251118
  • 质量门禁2.0:GitLab MR中AI风险预测阻断高危代码的技术方案
  • 20251119
  • 解方程(13年湛江一中自主招生)
  • 高德地图API的核心使用
  • 2.28 GBDT算法原理详解:梯度提升决策树,从数学推导到代码实现
  • 好写作AI:当AI承包了“码字”,你的大脑该升级什么技能?
  • 2026轻量化无人机建图识别系统供应商推荐:低空智能时代的核心引擎 - 品牌2025
  • 2.29 XGBoost、LightGBM、CatBoost对比:三大梯度提升框架选型指南
  • 如何科学分配Docker资源?看这篇就够了(附真实案例)
  • 2025年古法手工炒料火锅团建精选地点TOP4强力推荐,老火锅/牛肉火锅/酸汤火锅/火锅外卖/天台火锅古法手工炒料火锅团建地点有哪些 - 品牌推荐师
  • 2026年上海专业的孩子叛逆学校排行榜,精选孩子叛逆心理疏导与行为矫正机构推荐 - 工业品牌热点
  • 好写作AI:用好这把“学术赛车”,而不是让它替你“无证驾驶”
  • rancher kafka多监听配置
  • 2026年济南专业翻译公司顶尖推荐:济南译加翻译有限公司 - 2026年企业推荐榜
  • 好写作AI:不当你的“枪手”,只做你的“神装”
  • 2026深圳创业办公楼出租、联合办公室租赁推荐:5大优质产业园区含企业孵化园,助力创业腾飞 - 品牌2026
  • 2.31 机器学习神器项目实战:如何在真实项目中应用XGBoost等算法