进程调度算法

资源分配
资源 - cpu 内存 gpu等等

个人想法 (你是设计者,你该如何思考)
分配 - 排队算法(人 供销社 自由市场(为啥没有自由市场机制)时间片拍卖)任务的轻重缓急

(进程状态切换)堵塞和完成-就不是就绪态了

FCFS(先来先服务)

谁先排队(就绪队列,链表)

短作业优先调度 SJ(P)F

就绪队列选择估计运行时间最短的
(如何估计?)

高优先级优先调度算法(FPF)

非抢占式

叫号时先看等级,叫到了上桌了,来了大佬也不行

抢占式

大佬来了得立马让座

高响应比优先调度算法

优先级随着等待时间提高:响应比Rp * 你本身优先级

基于时间片的轮转调度算法

时间片轮转

吃饭有时间限制,不是等你吃完了或者没法吃了

多级反馈队列

结合上面几个优点
1.先根绝优先级排个队分为小桌 中桌 大桌(但不是同时进去,小桌吃完才到中桌,但中桌吃饭时间比小桌长)
2.小桌没吃完的去中桌等着继续吃
3.大桌就等前面吃完按时间来
4.来了可以优先级插队(优速通)

Linux CFS 调度器:原理、设计与内核实现

转:http://arthurchiao.art/blog/linux-cfs-design-and-implementation-zh/
公平的调度?

  • 实时任务的调度
  • 常规进程的调度

1.2.1 前提:CONFIG_CGROUPS
要实现按进程组分配和管理 CPU 份额的功能,首先要能够控制(control) 进程组(task group)的资源限额, 这种技术在 Linux 内核中已经有了,叫控制组(control group),缩写是 cgroup。 (CONFIG_CGROUPS)。

cgroup 是按资源类型(cpu/memory/device/hugetlb/…)来做资源限额的,每种资源 类型会有一种对应的控制器(controller),有独立的开关。 控制进程或进程组能使用的 CPU 时间,对应的开关是 CONFIG_CGROUP_SCHED。
至此,支持进程组级别资源控制的基础就具备了。接下来就是 CFS 扩展代码的实现, 添加对于 realtime/conventional task group 的支持。下面分别来看下。

存在的问题

某些情况下做不到真正的公平。

  1. CFS 本质上是会把 CPU 用满的(work-conserving)。具体来说,如果一个 CPU 上 有两个任务,理论上应该各占用 50% 的 CPU;但如果其中一个任务有很多 sleep/wait 时间, CFS 就会把多余的时间给到第二个进程,导致第二个进程实际使用的时间超过一半。

  2. 优先级高的进程仍然可能获得更大的时间片。

  3. 内核中有两中调度类(scheduling class):SCHED_RT 和 SCHED_NORMAL,前者的优先级更大。 当一个 CPU 上有 RT 类型任务时,永远是它们先执行。优先级可以通过 nice(2) 控制
    内核为每个 CPU 维护了一个可运行进程的队列(runqueue); CFS 有一个可配置的调度周期 sched_latency;接下来的基本调度过程:

CFS 根据当前可运行进程的数量 N,计算得到每个进程应该执行的时间 sched_latency/N;
依次取出进程执行以上计算出的时间;
如果 runqueue 有变化,再重新计算可执行时间。

核心数据结构

3.2.1 struct task_struct
每个进程的结构体表示是 struct task

3.2.2 struct task_group
同理,进程组中也有一个 struct sched_entity se 字段:

3.2.3 struct sched_entity
scheduling entities 通过一个红黑树组织到一起,根据 vruntime 排序,通过 cfs_rq 来管理.

所以 virtual runtime(vruntime)就定义在这个结构体里面,单位是 ns,

有了这个字段,就能精确地通过时间戳来保证一个任务应该获得的 “expected CPU time”。

前面已经提到,CFS 就是基于 p->se.vruntime 来选择(调度)进程的,逻辑非常简单: 永远选择 p->se.vruntime 最小(说明这个进程到目前为止累积执行的时间最少)的进程来运行。 CFS 会不断尝试均衡各进程的 CPU 时间,尽量接近“理想多任务 CPU”。

posted @ 2024-03-26 11:06  skyycj  阅读(3)  评论(0编辑  收藏  举报