Linux核心概念详解
  • 0. Linux核心概念详解
  • 1. 调试环境
  • 2. Linux 调度器
    • 2.1 任务
    • 2.2 核心概念
      • 2.2.1 核心概念 - 调度实体
      • 2.2.2 核心概念 - 调度类
      • 2.2.3 核心概念 - 调度策略
      • 2.2.4 核心概念 - 运行队列
      • 2.2.5 核心概念 - 优先级
    • 2.3 演进历史
      • 2.3.1 O(n)调度器 - 调度逻辑
      • 2.3.2 O(n)调度器 - 时间分配
      • 2.3.3 O(n)调度器 - 调度时机
      • 2.3.4 O(1)调度器 - 简介
      • 2.3.5 O(1)调度器 - 调度逻辑
      • 2.3.6 O(1)调度器 - 时间分配
      • 2.3.7 RSDL
      • 2.3.8 CFS
    • 2.4 DL调度器
      • 2.4.1 DL调度器 - 调度算法
      • 2.4.2 DL调度器 -核心代码
    • 2.5 RT调度器
    • 2.6 CFS
      • 2.6.1 公平性
      • 2.6.2 调度逻辑
      • 2.6.2.1 调度逻辑 - 数据结构
      • 2.6.2.2 调度逻辑 - vruntime
      • 2.6.2.3 调度逻辑 - 调度周期
      • 2.6.2.4 调度逻辑 - 调度节拍
      • 2.6.2.5 调度逻辑 - 任务抢占
      • 2.6.2.6 调度逻辑 - 调度时机
      • 2.6.3 组调度
      • 2.6.3.1 组调度 - 数据结构
      • 2.6.3.2 组调度 - 调度逻辑
      • 2.6.3.3 组调度 - 时间分配
      • 2.6.3.4 组调度 - 任务组权重
      • 2.6.4 带宽控制
      • 2.6.4.1 带宽控制 - 数据结构
      • 2.6.4.2 带宽控制 - 带宽时间
      • 2.6.4.3 带宽控制 - 挂起与解挂
      • 2.6.4.3 带宽控制 - 定时器
    • 2.7 负载追踪
      • 2.7.1 负载追踪 - 简介
      • 2.7.2 负载追踪 - 数据结构
      • 2.7.3 负载追踪 - 计算负载
      • 2.7.4 负载追踪 - 更新负载
    • 2.8 负载均衡
      • 2.8.1 简介
      • 2.8.2 CPU的拓扑结构
      • 2.8.3 数据结构
      • 2.8.4 算法思路
      • 2.8.5 触发时机
      • 2.8.6 总结
  • 3. LINUX 内存管理
    • 3.1 寻址模式
      • 3.1.1 地址
      • 3.1.2 地址转换
      • 3.1.3 Linux的地址空间
    • 3.2 物理内存
      • 3.2.1 数据结构
      • 3.2.2 初始化
      • 3.2.3 物理内存模型
      • 3.2.4 Buddy System(伙伴系统)
      • 3.2.5 SLAB/SLUB/SLOB
Powered by GitBook
On this page

Was this helpful?

  1. 2. Linux 调度器
  2. 2.2 核心概念

2.2.1 核心概念 - 调度实体

简要介绍调度器内部的调度单元,即Sched Entity

想要研究调度器的工作原理,我们首先需要了解调度器的工作对象。

在相当长的一段时间内,Linux 都将 task_struct 作为调度器的工作对象。但这样做存在一个问题,特别是在CFS引入之后,对时间公平性的讨论让这个问题更加明显。

为了解决调度时时间分配的公平性问题,Linux 在2.16版本中引入了CFS(Complete Fair Scheduler). 早期的CFS实现只在进程层面上实现了时间的公平分配,例如,如果一个系统有100个进程,CFS会保证每个进程都获得1%的CPU时间,但实际上系统中的这100个进程可能隶属于两个用户A与B, 其中用户A拥有10个进程,用户B拥有90个进程,这种实现造成的结果是用户A只获得了10%的CPU时间,而用户B获得了90%的时间。如果用户B了解CFS的调度原理,那么他可以肆无忌惮地fork出更多的进程以攫取更多的CPU时间。可见CFS在进程层面上的公平,却导致了系统在用户层面上的不公平,甚至是漏洞。对于这种情况,一种更合理的策略是系统首先保证每个用户获得相同的时间,然后再对隶属于同一个用户的所有进程公平地分配该用户的时间。

将该概念进一步抽象,我们就得到了进程组的概念。进程组的引入实际上是增加了一个调度层级,调度器首先完成进程组的时间分配,再处理组内进程之间的时间分配,前文提到的用户分组只是进程组的一个特例。

为了简化调度器模型,内核单独抽象出了一个概念叫“调度实体”,用来封装调度对象, struct task_struct 与调度实体相关的字段包括:

/* file: include/linux/sched.h */
struct task_struct {
    /* 调度实体,调度器的调度对象,该字段用于 CFS */
    struct sched_entity se;
    /* 该字段用于 RT 调度器 */
    struct sched_rt_entity rt;
#ifdef CONFIG_CGROUP_SCHED
    struct task_group *sched_task_group;
#endif
    /* 该字段用于 DL 调度器 */
    struct sched_dl_entity dl;
}

三个表示调度实体的字段 se, rt, dl 分别用于不同的调度策略。下一节将介绍调度策略的概念,而调度实体的详细信息与用法会在讲解调度策略的实现章节详细介绍。

Previous2.2 核心概念Next2.2.2 核心概念 - 调度类

Last updated 3 years ago

Was this helpful?