好好活就是有意义的事,有意义的事就是好好活
组调度与Cgroup : 跨线程的CPU资源如何分配?
组调度与Cgroup : 跨线程的CPU资源如何分配?

组调度与Cgroup : 跨线程的CPU资源如何分配?

前言

我之前曾写过一篇关于CFS和CPU Cgroup的文章, 系统的分析了OS如何基于CFS实现对CPU资源的限制:

从CFS的层面来分析docker是如何限制容器对CPU的使用的

但是我们默认, 只有一个进程(准确的说是, 进程只有一个主线程), 不同的进程在不同的Cgroup中. 这是Docker的标准运行方式, 即同进程的线程一定是属于同一个Cgroup的. 但是如果同进程的线程在不同的Cgroup中, 会如何瓜分CPU呢? 本文将全面刨析这个问题, 这也是本文的最重要的部分.

此外,关于组调度的学习, 是参考了此博客, 我是在其基础之上做了总结, 因此并不会详细的讲组调度:cgroup原理简析:进程调度 – 不爱洗脸 – 博客园​www.cnblogs.com/acool/p/6882644.html

此博文中有一个令人豁然开朗的配图, 我很喜欢:

preview

关于组调度:

(以下未区分进程和线程)

  • 根据优先级划分, 进程分为普通进程和实时进程
Linux 进程优先级
  • 实时进程会抢占普通进程的CPU, 且当存在实时进程时, 实时进程将会被优先调度, 在实时进程没有执行完成之前,普通进程不会被调度. 在Linux的调度实现中, 存在两个调度类, 即实时调度类和CFS调度类, 前者使用FIFO或RR的调度算法, 后者使用CFS调度算法. 调度策略会先检查实时调度类的运行队列(即上图中的re_rq)是否为空, 即优先保证实时进程的运行.
  • 不过无论是CFS还是RT, 其最终目标都是选择一个线程来执行, 但是在运行队列中排队的结构其实是一个调度实体(SE).
  • 调度实体(SE)可能是一个线程,或者是一个调度组. 如果调度器选择的SE是一个线程, 那么选择的任务结束. 如果SE是一个调度组, 那么将在调度组中重新选择新的调度实体, 直到选中一个线程为止.
  • Cgroup则对应了调度组. Root Cgrou则是最大的调度组, 每次调度都将从Root Cgroup中开始.

调度组的CPU资源划分

时间片的分配, 是根据SE进行的, 一个调度组的所有SE共享该调度组的CPU资源, 假设本机拥有4个core, Cgroup结构如下:

进程P1, P2 各包含4个线程, 其中P2的4个线程完全在Cgroup-4中, P2的4个线程, 以不同的比例分配在Cgroup-1和Cgroup-3中, 则P1, P2的CPU资源最终分配比例如下:

P1 在 Cgroup-1中的线程数P1 在 Cgroup-3中的线程数P1 : P2 的CPU占比
041 : 1
135 : 3
223 : 1
315 : 1
402 : 1

我们这里以1 : 3的分配比分析:

  • 首先C-1 比 C-2 的shares权重是2:1, 因此 C-1理论上应该占据4 * 2/3 个core
  • 但是C-1 中只有一个线程, 因此C-1最终拥有1个core全部分配给P1
  • C-3 和 C-4将平分C-2的3个core, 每人各拿 3/2个core, 分别分配给P1和P2
  • 最终P1 拥有 1+ 3/2个core, P2拥有3/2个core

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注