linux 调度

Linux调度器的演变

轮转调度RR

Round Robin

完全公平调度器CFS

Complete Fair Schedule

异构多处理HMP

Heterogeneous Multi-Processing

功耗感知调度EAS

Enery Aware Schedule

在这里插入图片描述

CFS 调度器概念 ( 完全公平调度器 )

CFS 调度器 ( Completely Fair Scheduler ) 是 " 完全公平调度器 " , " 完全公平调度算法 " 对每个 进程 都是公平的 ,

" 完全公平调度算法 " 是 基于时间片轮询 的 调度算法 ,

每个进程 都会获得一段 相同的大小的 CPU 时间片 来运行 ;

CFS 调度器 没有 时间片概念 , 该调度器会 公平地 分配 CPU 的使用时间 ;

举例说明 : 如果有 4 个相同 优先级 的进程运行在 同一个 CPU 上 , 每个进程都会被 公平 分配到 25% 的运行时间 ;

CFS 调度器虚拟时钟概念 ( Virtual Runtime )

CFS 调度器 中 , 定义了 一种 " 调度模型 " , 该 模型 为 CFS 执行队列 cfs_rq 中的 每个进程 都设置了 虚拟时钟 Virtual Runtime ;

被设置了 虚拟时钟 的进程 , 执行 n 时长后 , 其 虚拟时钟 会增加 n 时长 , 其它 没有执行的进程 虚拟时钟 值保持不变 ;

进程优先级 ( 调度优先级 | 静态优先级 | 正常优先级 | 实时优先级 )

进程优先级相关字段

在 linux-5.6.18\include\linux\sched.h 头文件中 task_struct " 进程描述符 " 结构体 中定义了 进程优先级字段如下 :

int				prio; 				 // 调度优先级
int				static_prio; 		 // 静态优先级
int				normal_prio; 		 // 正常优先级
unsigned int			rt_priority; // 实时优先级

1、prio 字段 ( 调度优先级 )

prio 字段 是 " 调度优先级 " , 数值越小 , 优先级越高 ;

一般情况下 prio 字段 等于 normal_prio 字段 ;

特殊情况 : 在锁同步机制中 , 如果 A 进程 占有了 实时互斥锁 , B 进程 等待该 实时互斥锁 , 假如 B 进程的优先级 高于 A 进程 的优先级 , 此时就会将 占有 实时互斥锁 的 A 进程的 prio 优先级 提高到与 B 进程 prio 优先级相等的地位 ;

2、static_prio 字段 ( 静态优先级 )

static_prio 字段 是 " 静态优先级 " ,

对于 " 限期进程 " 来说 , 静态优先级 static_prio 字段 值总为 0 , 没有意义 ;

对于 " 实时进程 " 来说 , 静态优先级 static_prio 字段 值总为 0 , 没有意义 ;

对于 " 普通进程 " 来说 , 静态优先级 static_prio 字段 值为 120 + nice , 其数值越小 , 优先级越高 ;

3、normal_prio 字段 ( 正常优先级 )

normal_prio 字段 是 " 正常优先级 " , 数值越小 , 优先级越高 ,

对于 " 限期进程 " 来说 , 正常优先级 normal_prio 字段 值总为 -1 ;

对于 " 实时进程 " 来说 , 正常优先级 normal_prio 字段 值 99 - rt_priority ;

对于 " 普通进程 " 来说 , 正常优先级 normal_prio 字段 值 与 静态优先级 static_prio 字段相等 , 为 120+nice , 其数值越小 , 优先级越高 ;

4、rt_priority 字段 ( 实时优先级 )

rt_priority 字段 是 " 实时优先级 " ,

对于 " 限期进程 " 来说 , 实时优先级 rt_priority 字段 值总为 0 , 没有意义 ;

对于 " 实时进程 " 来说 , 实时优先级 rt_priority 字段 值为 1~99 , 其数值越大 , 优先级越高 ;

对于 " 普通进程 " 来说 , 实时优先级 rt_priority 字段 值总为 0 , 没有意义 ;

在这里插入图片描述

Linux系统中进程的nice值与优先级

https://blog.youkuaiyun.com/qq_39599464/article/details/114402346

CFS 调度器 " 权重 " 概念

CFS 调度器 ( Completely Fair Scheduler ) " 完全公平调度器 " ,实际运行过程中 ,会涉及到 具有 不同 " 进程优先级 " 的 进程 之间的调度 , 有些进程 优先级高 , 有些进程 优先级低 ,为了避免 优先级低 的进程 始终无法得到 CPU 时间 执行 , 向每个进程提供 公平 调度 , CFS 调度器 引入了 " 权重 " 概念 , CFS 使用 " 权重 " 值 , 替代 进程的 优先级 , 不同 " 进程优先级 " 的进程 会按照 权重比例 , 分配 CPU 的执行时间。

CFS 调度器调度实例 ( 计算进程 " 实际运行时间 " )

有 2 个进程 A 和 B , 在 CPU 上执行 ;

A 进程的 权重 为 512 , B 进程的 权重 为 1024 ;

在 CPU 上执行的进程 可获取到的 CPU 时间比例 计算公式如下 :

A进程获取的CPU时间比例 = 所有进程的权重之和 / A进程权重

A 进程获取的CPU 时间比例 = A 进程权重 / 所有进程的权重之和 = 512 / (512 + 1024) = 1 / 3

CPU 的总时间是 CPU的调度区(调度周期) 大小 , 则 进程 在 CPU 上执行的进程 可获取到的 CPU时间 计算公式如下 :

进程获取的CPU时间 = 调度区 × 所有进程的权重之和 / 进程权重

计算进程 " 虚拟运行时间 "

虚拟运行时间的引入

CFS为了实现公平,必须惩罚当前正在运行的进程,以使那些正在等待的进程下次被调度。

具体实现时,CFS通过每个进程的虚拟运行时间(vruntime)来衡量哪个进程最值得被调度。

CFS中的就绪队列是一棵以vruntime为键值的红黑树,虚拟时间越小的进程越靠近整个红黑树的最左端。因此,调度器每次选择位于红黑树最左端的那个进程,该进程的vruntime最小

虚拟运行时间是通过进程的实际运行时间和进程的权重(weight)计算出来的。

在CFS调度器中,将进程优先级这个概念弱化,而是强调进程的权重。一个进程的权重越大,则说明这个进程更需要运行,因此它的虚拟运行时间就越小,这样被调度的机会就越大。

那么,在用户态进程的优先级nice值与CFS调度器中的权重又有什么关系?在内核中通过prio_to_weight数组进行nice值和权重的转换。

每一个进程拥有一个vruntime,每次需要调度的时候就选运行队列中拥有最小vruntime的那个进程来运行,vruntime在时钟中断里面被维护,每次时钟中断都要更新当前进程的vruntime,即vruntime以如下公式逐渐增长:

在这里插入图片描述

http://t.zoukankan.com/linhaostudy-p-9946814.html

在这里插入图片描述

通过上述公式 , 可以得出 :

在 相同的 调度周期 中 , 所有 运行在该 CPU 上的进程 的 " 虚拟运行时间 " 是相同的 ,

在 CFS 调度器 对 进程 进行调度运行时 , 找到 " 虚拟运行时间 " 最小的进程 运行即可 ,

Linux 内核中 , 进程队列 的数据结构是 " 红黑树 " , 该数据结构 可以最快地找到 " 虚拟运行时间 " 最小的进程 ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值