一、概述

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

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

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

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

二、CPU调度器

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

多个task会共享CPU资源

那如何进行任务切换选择呢?

当前运行的task中止

当前运行的task sleep(wait event)

新task创建,或者sleep的task唤醒了

当前运行的task的时间片用完

那调度器的目标是什么?

公平调度各个task

基于task的优先级来分配时间片

task的respnse时间短

高throughput(task执行成功)

在多个cpu间,负载均衡

低功耗

调度器代码运行开销低

调度器会和工作在一些框架、服务器、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结构体实现:

structsched_class {const struct sched_class *next;void (*enqueue_task) (struct rq *rq, struct task_struct *p, intflags);void (*dequeue_task) (struct rq *rq, struct task_struct *p, intflags);

...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))gotoagain;returnp;

}

}/*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中由很多其他的信息和状态

structrq {

...structcfs_rq cfs;structrt_rq rt;structdl_rq dl;

...

}

linux 4.1.16 ftrace 进程调度,Linux内核进程调度overview(1)相关推荐

  1. linux od 命令16进制,Linux od命令

    Linux od命令 Linux od命令用于输出文件内容. od指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来. 语法 od [-abcdfhilovx][-A ][-j ][-N ] ...

  2. linux shell 桌面,16个桌面Linux用户必须要知道的Shell命令

    有些人仍然会有这中愚蠢的想法,他们认为使用就必须使用Linux命令.胡说!你可以不懂得任何Linux命令,比如说ps,grep,ls等,但是你仍然可以使用很多现代的Linux桌面发行版. 5D9p:B ...

  3. 使用 ftrace 调试 Linux 内核【转】

    转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...

  4. 使用 ftrace 调试 Linux 内核,第 2 部分

    ftrace 操作概述 使用 ftrace 提供的跟踪器来调试或者分析内核时需要如下操作: 切换到目录 /sys/kernel/debug/tracing/ 下 查看 available_tracer ...

  5. linux 2.6.23时钟中断与调度分析,进程调度Linux内核分析ppt课件

    <进程调度Linux内核分析ppt课件>由会员分享,可在线阅读,更多相关<进程调度Linux内核分析ppt课件(26页珍藏版)>请在人人文库网上搜索. 1.Linux操作系统分 ...

  6. linux 2.6内核进程调度,linux2.6内核进程调度

    Linux2.4内核进程调度的缺陷: Linux2.4 内核的进程调度采用时间片轮转和优先级相结合的调度策略,但存在以下几个致命缺陷: 1>调度算法时间复杂度是 O(n).2.4 内核每次调度都 ...

  7. linux 2.6内核进程调度,Linux2.6内核进程调度系列--scheduler_tick()函数2.更新实时进程的时间片,...

    Linux2.6内核进程调度系列--scheduler_tick()函数2.更新实时进程的时间片, RT /** * 递减当前进程的时间片计数器,并检查是否已经用完时间片. * 由于进程的调度类型不同 ...

  8. linux 终端 画圆,16个圆桌面Linux用户必须要知道的Shell命令

    16个圆桌面Linux用户必须要知道的Shell命令 16个圆桌面Linux用户必须要知道的Shell命令 日期:2014-05-16 浏览次数:20305 次 16个桌面Linux用户必须要知道的S ...

  9. linux选择运行的核数量,linux – 如何根据可用内核的数量选择最大负载阈值?

    负载在Linux上经常被误解. 在Linux上,它是运行或不间断睡眠状态中所有任务的度量. 请注意,这是任务,而不是进程.线程包含在此值中. 内核每五秒计算一次加载,并且是一个加权平均值.这是微小负载 ...

最新文章

  1. Linux进程突然挂死,当主进程突然死亡时,我该如何杀死linux spawnProcess?
  2. 如何自学python爬虫-怎样入门学习Python爬虫?
  3. VTK:PolyData之PolyDataToUnstructuredGrid
  4. 【初级】String str= ac,42,123,sd Fa,c df,4,acdf,5ewRRre ;1.把字符串按,进行分割
  5. 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
  6. LeetCode算法入门- Compare Version Numbers -day14
  7. 兰州大学c语言课程作业答案,兰州大学C语言程序设计课程作业1.doc
  8. 2017 前端大事件和趋势回顾,2018 何去何从?
  9. 【python】os 模块使用笔记
  10. win10必须禁用的服务_关闭这几个系统服务,让你的电脑不再卡!
  11. 贴片钽电容封装及规格参数资料
  12. intel i5处理器layout及原理图参考
  13. 计算机网络 - 练习(一百二十七)
  14. 转载 : 10大H5前端框架
  15. GIS制图的基础三点
  16. 搭建用户增长体系,这5个方法告诉你怎么做
  17. 什么是软件危机?软件危机的主要表现是什么?什么是软件?什么是软件工程?什么是软件过程?软件过程与软件工程方法学有何关系?​​​​​​​什么是软件开发方法?软件开发方法主要有哪些?
  18. 新开淘宝店铺如何推广运营
  19. 华为“天才少年” DIY 生日礼物:四个月打造能缝葡萄的机械臂!
  20. 小程序云开发 ——微信支付

热门文章

  1. getter/setter_Getters / Setters。 邪恶。 期。
  2. 成为Java流大师–第1部分:创建流
  3. jsr 107_如何使用JSR107缓存注释
  4. 10个步骤的筛选器模式
  5. [EBOOK]十大Java性能问题
  6. 使用Gradle禁止Java和Spring Boot Web应用程序中的FindBugs警告
  7. 将2个字符写入单个Java char
  8. java java se_Java SE 7、8、9 –推动Java前进
  9. Tomcat到Wildfly:配置数据库连接
  10. Hazelcast的MapLoader陷阱