一、概述

  决定何时、如何选择一个新进程运行的这组规则叫做:调度策略(scheduling policy)。

  Linux的调度是基于分时技术(time sharing):多个进程以“时间多路复用”方式运行,因为CPU的时间呗分成“片”(slice),给每个可运行进程分配一片。如果当前运行进程的时间片或时限(quantum)到期时,该进程还没有运行完毕,进程切换就会发生。

  调度策略也是根据进程的优先级对它们进行分类。在Linux中,进程优先级是动态的:在较长时间内没有运行的进程,会动态提升它们的优先级;相反地,对于在CPU上运行较长时间的进程,会降低它们的优先级来惩罚它们。

  所以,实现调度的工具是调度器(scheduler),调度的对象是进程(process),调度的方法是调度策略(包括调度算法)。

二、CPU调度器

这里主要讲了cpu调度器的工作内容和目的:

  1. 多个task会共享CPU资源
  2. 那如何进行任务切换选择呢?
    • 当前运行的task中止
    • 当前运行的task sleep(wait event)
    • 新task创建,或者sleep的task唤醒了
    • 当前运行的task的时间片用完

那调度器的目标是什么?

  1. 公平调度各个task
  2. 基于task的优先级来分配时间片
  3. task的respnse时间短
  4. 高throughput(task执行成功)
  5. 在多个cpu间,负载均衡
  6. 低功耗
  7. 调度器代码运行开销低

调度器会和工作在一些框架、服务器、PC、嵌入式/手机中。

三、O(1)调度器

在2.6.23(2007)以前,Linux调度器使用的是O(1)调度器:

  • 调度器分140个优先级等级:0-99是RT task,100-139是User task
  • 每个cpu的runqueue有2个数组:Active,Expaired
  • 每个数组都有140个entry,对应每个优先级
  • 每个entry是一条FIFO队列结构的链表
  • 140位的bitmap用来检测每个优先级list
  • 时间片会根据task的优先级进行分配
  • 运行时间expaire的task会从Active数组移动到Expaired数组
  • 当Active数组为空时,就交换2个数组。即,将Expaired数组变为Active;Active(此时为空)变为Expaired
  • task的入rq和出rq,以及next task的选择都是在固定时间内完成

最后在O(1)调度器已经被CFS替代。

四、当前调度器架构

  • 在kernel 2.6.23(2007)后,由Ingo Molnar引入
  • 在调度的class中,还存在调度policy
  • 不同的调度class,高优先级的,越早执行
  • task可以在cpu、调度policy、调度class间进行迁移

4.1  调度class

由struce sched_class结构体实现:

struct sched_class {
const struct sched_class *next;
void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
...
struct task_struct * (*pick_next_task) (struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
...
};

内核中一共有5中调度class,优先级从高到低:STOP > DL > RT > CFS > IDLE,他们通过链表实现,并链接起来的。

4.2  主调度函数Schedule()

内核中进程调度,最主要的实现是Schedule()函数。它完成如下工作:

  • 选取下一个runnable的task,并将task放在cpu上运行
  • 按class优先级搜索task来运行,最先从STOP class开始
  • 轮询搜索:for_each_class()
  • 实现方式:pick_next_task():
again:
for_each_class(class) {
p = class->pick_next_task(rq, prev, rf);
if (p) {
if (unlikely(p == RETRY_TASK))
goto again;
return p;
}
} /* The idle class should always have a runnable task: */
BUG();

4.3  调度class与policy

在不同的调度class下,可能会有不同的调度policy实现:

● Stop
  ○ No policy
● Deadline
  ○ SCHED_DEADLINE
● Real Time
  ○ SCHED_FIFO
  ○ SCHED_RR
● Fair
  ○ SCHED_NORMAL
  ○ SCHED_BATCH
  ○ SCHED_IDLE
● Idle
  ○ No policy

不同的class代表不同的调度优先级;不同的policy同样也意味着不同的调度方式。

4.4  调度class:STOP

STOP类型的class有如下特点:

  • 是最高优先级的class(但是这个class不开放给系统user使用的)
  • 只能在smp系统上可用(stop_machine()在单核处理器下不可用)------括号内的具体没怎么理解
  • 可以抢占所有task,并任何事件都不能抢占它
  • 实现方式是:停止运行的其他所有task,而在cpu上运行一个特定的函数
  • 没有调度policy
  • 属于stop class的per cpu内核线程:migration/N ------“N”为cpu core number
  • 在以下情况下使用:task迁移、CPU hotplug、RCU、ftrace、cloclevents等

4.5  调度class:Deadline(DL)

Deadline类型的class有如下特点:

  • 在kernel 3.14(2013),由Dario Faggioli & Juri Lelli引入
  • 在系统中,属于可以使用的最高优先级的class
  • 调度policy为SCHED_DEADLINE
  • 由红黑树结构实现(自平衡树)
  • 在以下情况下使用:周期性的实时task,例如:视频编解码

4.6  调度Real-time(RT)

Real-time类型的class有如下特点:

  • 符合POSIX标准要求
  • task优先级范围:0-99
  • 优先级在kernel和userspace中相反:0在kernel中,代表最高优先级;而在userspace中代表最低优先级
  • 相同优先级下的调度policy:
    • SCHED_FIFO
    • SCHED_RR,默认时间片长度为100ms
  • 由链表实现
  • 在以下情况下使用:latency敏感的task,例如:IRQ threads

4.7  调度CFS(Completely Fair Scheduler)

CFS类型的class有如下特点:

  • 由Ingo Molnar引入
  • 调度policy:
    • SCHED_NORMAL:普通task
    • SCHED_BATCH:批处理 task(batch task,非交互型)
    • SCHED_IDLE:低优先级task
  • 由红黑树结构实现
  • 跟踪task的虚拟运行时间(vruntime,task拥有的运行时间)
  • 虚拟运行时间(vruntime)最短的task,最优先运行
  • task的优先级作为权重,会影响虚拟运行时间的计算(vruntime)
  • 权重越大,虚拟运行时间(vruntime)计算时的增量就越小
  • task的优先级计算:120+nice值(nice范围:-20 ~ +19)
  • 用于所有其他类型的task,例如:shell

4.7  调度Idle

Idle类型的class有如下特点:

  • 最低优先级的调度class
  • 没有调度policy
  • 属于idle class的per cpu内核线程(idle):swapper/N ------“N”为cpu core number
  • idle线程仅会在没有其他task的情况下,在cpu上运行
  • idle线程可以让cpu进入低功耗状态

五、Runqueue

  • 每个CPU都由一个struct rq的实例
  • 每个”rq“包含了DL、RT、CFS的runqueue
  • Runnable的task会被压入上面提到的那些runqueue中
  • 在struct rq中由很多其他的信息和状态
struct rq {
...
struct cfs_rq cfs;
struct rt_rq rt;
struct dl_rq dl;
...
}

Linux内核进程调度overview(1)的更多相关文章

  1. linux内核 进程调度

    概念: 进程调度决定那个进程投入运行,运行多长时间. 进程调度没有太复杂的原理,最大限度的利用处理器时间的原则是:只要有可执行的程序,那么总会有进程在执行,如果可运行的进程比处理器数目要多,那么注定要 ...

  2. Linux内核分析:实验八--Linux进程调度与切换

    刘畅 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 概述 这篇文章主要分析Li ...

  3. 第3章(1) Linux内核相关概念

    Linux内核的组成 1. Linux内核源代码的目录结构 arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如 i386.arm. arm64.powerpc.mips 等.Linu ...

  4. 《Linux内核设计与实现》读书笔记 第四章 进程调度

    第四章进程调度 进程调度程序可看做在可运行太进程之间分配有限的处理器时间资源的内核子系统.调度程序是多任务操作系统的基础.通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发执行的 ...

  5. linux 内核学习之八 进程调度过程分析

    一  关于进程的补充 进程调度的时机 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule() ...

  6. Linux内核分析——理解进程调度时机跟踪分析进程调度与进程切换的过程

    20135125陈智威 +原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验 ...

  7. Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程

    一.原理分析 1.调度时机 背景不同类型的进程有不同的调度需求第一种分类I/O-bond:频繁的进行I/O:通常会花费很多时间等待I/O操作的完成CPU-bound:计算密集型:需要大量的CPU时间进 ...

  8. Linux内核分析--理解进程调度时机、跟踪分析进程调度和进程切换的过程

    ID:fuchen1994 姓名:江军 作业要求: 理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否 ...

  9. 【读书笔记】《Linux内核设计与实现》进程管理与进程调度

    大学跟老师做嵌入式项目,写过I2C的设备驱动,但对Linux内核的了解也仅限于此.Android系统许多导致root的漏洞都是内核中的,研究起来很有趣,但看相关的分析文章总感觉隔着一层窗户纸,不能完全 ...

随机推荐

  1. 002_python的in,while else,格式化输出,逻辑运算符,int与bool转换,编码

    数据 1.什么是数据? x=10,10是我们要存储的数据 2.为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3.数据类型 数字 字符串 列表 元组 字典 集合 ...

  2. 【HBase】带你了解一哈HBase的各种预分区

    目录 简单了解 概述 设置预分区 一.手动指定预分区 二.使用16进制算法生成预分区 三.将分区规则写在文本文件中 四.使用JavaAPI进行预分区 简单了解 概述 由上图可以看出,每一个表都有属于自 ...

  3. 【Hadoop离线基础总结】Hive级联求和

    Hive级联求和 建表 CREATE TABLE t_salary_detail( username string, month string, salary INT ) ROW format del ...

  4. docker-compose安装rabbitmq集群(主从集群---》镜像集群)

    docker-compose安装rabbitmq集群(主从集群--->镜像集群) yls 2020/5/11 创建docker-compose.yml 文件 version: '3' servi ...

  5. Vular开发手记#1:设计并实现一个拼插式应用程序框架

    可视化编(rxeditor)辑告一段落,在知乎上发了一个问题,询问前景,虽然看好的不多,但是关注度还是有的,目前为止积累了21w流量,因为这个事,开心了好长一段时间.这一个月的时间,主要在设计制作Vu ...

  6. [hdu5101]计数问题

    http://acm.hdu.edu.cn/showproblem.php?pid=5101 题目大意:给n个集合,求从两个不同集合里面各取一个数使得它们的和大于给定数的方案数. ans=从所有数里面 ...

  7. 初识spring boot maven管理--SpringMVC

    springboot完美的支持了springmvc,自家东西当然是支持最好的啦! @EnableAutoConfiguration自动注入了一下信息 1.包含了ContentNegotiatingVi ...

  8. 常用DOS命令大全

    常用DOS命令大全 常用的内部命令有MD.CD.RD.DIR.PATH.COPY.TYPE.EDIT.REN.DEL.CLS.VER.DATE.TIME.PROMPT 常用的外部命令有DELTREE. ...

  9. 1、Fiddler基础

    1.抓取https请求 前言 fiddler是一个很好的抓包工具,默认是抓http请求的,对于pc上的https请求,会提示网页不安全,这时候需要在浏览器上安装证书. 一.网页不安全 1.用fiddl ...

  10. ES6,ES7,ES8 常用

    ES6常用新特性 let && const let 命令也用于变量声明,但是作用域为局部 { let a = 10; var b = 1; } 在函数外部可以获取到b,获取不到a,因此 ...