文章插图
所以 O(n) 调度器有如下缺陷:
- 时间复杂度是 O(n) , 运行队列中的任务数目越大 , 调度器的效率就越低 。
- 实时进程不能及时调度 , 因为实时进程和普通进程在一个列表中 , 每次查实时进程时 , 都需要全部扫描整个列表 , 所以实时进程不是很“实时” 。
- SMP 系统不好 , 因为只有一个 runqueue , 选择下一个任务时 , 需要对这个 runqueue 队列进行加锁操作 , 当任务较多的时候 , 则在临界区的时间就比较长 , 导致其余的 CPU 自旋浪费 。
- CPU空转的现象存在 , 因为系统中只有一个runqueue , 当运行队列中的任务少于 CPU 的个数时 , 其余的 CPU 则是 idle 状态 。

文章插图
总的来说 O(1) 调度器的出现是为了解决 O(n) 调度器不能解决的问题 , 但 O(1) 调度器有个问题 , 一个高优先级多线程的应用会比低优先级单线程的应用获得更多的资源 , 这就会导致一个调度周期内 , 低优先级的应用可能一直无法响应 , 直到高优先级应用结束 。CFS调度器就是站在一视同仁的角度解决了这个问题 , 保证在一个调度周期内每个任务都有执行的机会 , 执行时间的长短 , 取决于任务的权重 。下面详细看下CFS调度器是如何动态调整任务的运行时间 , 达到公平调度的 。
CFS 调度器CFS是 Completely Fair Scheduler 简称 , 即完全公平调度器 。CFS 调度器和以往的调度器不同之处在于没有固定时间片的概念 , 而是公平分配 CPU 使用的时间 。比如:2个优先级相同的任务在一个 CPU 上运行 , 那么每个任务都将会分配一半的 CPU 运行时间 , 这就是要实现的公平 。
但现实中 , 必然是有的任务优先级高 , 有的任务优先级低 。CFS 调度器引入权重 weight 的概念 , 用 weight 代表任务的优先级 , 各个任务按照 weight 的比例分配 CPU 的时间 。比如:2个任务A和B , A的权重是1024 , B的权重是2048 , 则A占 1024/(1024+2048) = 33.3% 的 CPU 时间 , B占 2048/(1024+2048)=66.7% 的 CPU 时间 。
在引入权重之后 , 分配给进程的时间计算公式如下:
实际运行时间 = 调度周期 * 进程权重 / 所有进程权重之和
CFS 调度器用nice值表示优先级 , 取值范围是[-20, 19] , nice和权重是一一对应的关系 。数值越小代表优先级越大 , 同时也意味着权重值越大 , nice值和权重之间的转换关系:
const int sched_prio_to_weight[40] = { /* -20 */ 88761, 71755, 56483, 46273, 36291, /* -15 */ 29154, 23254, 18705, 14949, 11916, /* -10 */ 9548, 7620, 6100, 4904, 3906, /* -5 */ 3121, 2501, 1991, 1586, 1277, /* 0 */ 1024, 820, 655, 526, 423, /* 5 */ 335, 272, 215, 172, 137, /* 10 */ 110, 87, 70, 56, 45, /* 15 */ 36, 29, 23, 18, 15,};
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 黑客如何搭建和使用VMware和Kali Linux使用环境?
- 彻底搞懂Java线程池的工作原理
- 电脑鼠标右键菜单管理及彻底删除方法技巧
- Kali Linux,一个你欲罢不能的东西,非专业勿入
- Linux 命令总结
- 50个应知必会的Linux常识和操作
- 详细解析Linux /etc/passwd文件
- Linux系统安全攻防技术
- Linux 怎么修改最大文件打开数量?
- Linux经典面试题:网卡接收数据后,经过几次拷贝才能到用户进程
