调度器结构图:
各个调度器类之间具备一定的层次关系,即在通用调度器选择进程的时候,会从最高优先级的调度器类开始选择。
Linux 系统的调度
Linux 系统的进程调度策略
Linux进程调度策略(三种):
实时进程的调度策略是SCHED_FIFO和SCHED_RR,非实时进程的调度策略(分时调度策略)是SCHED_NORMAL(SCHED_OTHER)即完全公平调度CFS。
Linux 系统的调度器类
1、停机调度类 ( stop_sched_class )
优先级最高 , 用于停止进程 , 该调度类可以抢占系统进程 ;
2、限期调度类 ( dl_sched_class )
按照优先算法调度进程 , 将进程按照绝对截止期限从小到大在红黑树中进行排序;
调度时 , 每次都选择截止期限最小的 " 进程 " 执行 ;
3、实时调度类 ( rt_sched_class )
为每个 " 调度优先级 " 维护一个 队列 ;
4、公平调度类 ( fair_sched_class )
引入一个完全公平的调度算法 ,给每个进程都设置一个 " 虚拟运行时间 " (vruntime)概念 。如果一个进程得以执行,随着执行时间的不断增长,其vruntime也将不断增大,没有得到执行的进程vruntime将保持不变。
而调度器将会选择最小的vruntime那个进程来执行。这就是所谓的完全公平调度CFS。不同优先级的进程其vruntime增长速度不同,优先级高的进程vruntime增长得慢,所以它可能得到更多的运行机会。
计算公式:vruntime = (调度周期 * 当前进程权重 / 所有进程权重总和) * NICE_0_LOAD/ 当前进程权重
= 调度周期 * NICE_0_LOAD/ 所有进程权重总和
- vruntime:虚拟时钟,运行时间增,vruntime增,
- nice:(取值-20~19,默认0)值越大,优先级越低。且nice = 权重≠时间片大小
然后根据每一个进程或者调度组都对应一个调度的实体并与CFS运行队列建立联系,每次进行CFS调度的时候都会在CFS运行队列红黑树中选择一个进程(vruntime值较小者)。cfs_rq代表CFS运行队列,它可以找到对应的红黑树。进程task_struct ,可以找到对应的调度实体。调度实体sched_entity对应运行对列红黑树上的一个节点。
5、空闲调度类 ( idle_sched_class )
每个 CPU 上都有一个空闲线程即 0 号线程 ;
优先级最低 , 只有在其它类型的调度类进程都执行完毕后 , 才会执行空闲调度类对应的进程 ;