1. 概述
(1) Completely Fair Scheduler,完全公平调度器,用于Linux系统中普通进程的调度。
(2) CFS采用了红黑树算法来管理所有的调度实体 sched_entity,算法效率为O(log(n))。CFS跟踪调度实体sched_entity的虚拟运行时间vruntime,平等对待运行队列中的调度实体sched_entity,将执行时间少的调度实体sched_entity排列到红黑树的左边。
(3) 调度实体sched_entity通过 enqueue_entity()和 dequeue_entity()来进行红黑树的出队入队。
文章推荐视频:
C/C++Linux后台服务器开发高级架构师免费学习链接:C/C++Linux服务器开发高级架构师/Linux后台架构师-学习视频
老规矩,先上张图片来直观了解一下原理:
(1) 每个 sched_latency 周期内,根据各个任务的权重值,可以计算出运行时间 runtime;
(2) 运行时间runtime可以转换成虚拟运行时间vruntime;
(3) 根据虚拟运行时间的大小,插入到CFS红黑树中,虚拟运行时间少的调度实体放置到左边;
(4) 在下一次任务调度的时候,选择虚拟运行时间少的调度实体来运行;
2. 数据结构
2.1 调度类
Linux内核抽象了一个调度类struct sched_class,这是一种典型的面向对象的设计思想,将共性的特征抽象出来封装成类,在实例化各个调度器的时候,可以根据具体的调度算法来实现。这种方式做到了高内聚低耦合,同时又很容易扩展新的调度器。
在调度核心代码kernel/sched/core.c中,使用的方式是task->sched_class->xxx_func, 其中task表示的是描述任务的结构体struct task_struct,在该结构体中包含了任务所使用的调度器,进而能找到对应的函数指针来完成调用执行,有点类似于C++中的多态机制。
2.2 rq/cfs_rq/task_struct/task_group/sched_entity
(1) struct rq:每个CPU都有一个对应的运行队列;
(2) struct cfs_rq:CFS运行队列,该结构中包含了struct rb_root_cached红黑树,用于链接调度实体struct sched_entity。rq运行队列中对应了一个CFS运行队列,此外,在task_group结构中也会为每个CPU再维护一个CFS运行队列;
(3) struct task_struct:任务的描述符,包含了进程的所有信息,该结构中的struct sched_entity,用于参与CFS的调度;
(4) struct task_group:组调度(参考前文),Linux支持将任务分组来对CPU资源进行分配管理,该结构中为系统中的每个CPU都分配了struct sched_entity调度实体和struct cfs_rq运行队列,其中struct sched_entity用于参与CFS的调度;
(5) struct sched_entity:调度实体,这个也是CFS调度管理的对象了;
C/C++Linux后台服务器开发高级架构师学习视频 点击 linux服务器学习资料 获取,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,