本次分析的kernel代码为2.6.32-220。并且我们先不考虑SMP。当前linux的调度程序由两个调度器组成:主调度器,周期性调度器(两者又统称为核心调度器);并且每个调度器包括两个内容:调度框架(其实质就是两个函数框架)及调度器类。调度器类是实现了不同调度策略的实例,如 CFS、RT class。它们的关系如下图:


图 调度器的组成

当前的内核支持两种调度器类(sched_setscheduler系统调用可修改进程的策略):CFS(公平)、RT(实时);5种调度策略:SCHED_NORAML(最常见的策略)、SCHED_BATCH(除了不能抢占外与常规任务一样,允许任务运行更长时间,更好地使用高速缓存,适合于成批处理的工作)、SCHED_IDLE(它甚至比nice 19还有弱,为了避免优先级反转使用)和SCHED_RR(循环调度,拥有时间片,结束后放在队列末)、SCHED_FIFO(没有时间片,可以运行任意长的时间);其中前面三种策略使用的是cfs调度器类,后面两种使用rt调度器类。
         另外,对于调度框架及调度器类,它们都有自己管理的运行队列,调度框架只识别rq(其实它也不能算是运行队列),而对于cfs调度器类它的运行队列则是cfs_rq(内部使用红黑树组织调度实体),实时rt的运行队列则为rt_rq(内部使用优先级bitmap+双向链表组织调度实体)。下图调度器相关的几个数据结构的关系:


图 调度器结构关系图

Rq表示调度框架上的运行队列(它本身并没有真正组织调度实体,而是它下面的cfs及rq两个成员负责组织真正的调度实体),在多核处理器上每个cpu有一个rq结构.
rq#cpu运行队列,每个cpu一个
nr_running:表示总共就绪的进程数(包括cfs,rq及正在运行的)
cpu_load[]:表示该rq所在cpu的历史load,一般有5个
load:表示当前cpu的load,这个load是它所有就绪进程的load之和(同样包括cfs,rq及正在运行的)
nr_swithces:进行上下文切换的次数
cfs:该rq所包括的cfs_rq运行队列,这个是所有cfs_rq的root

rt:与上面的cfs类似
curr:当前正在运行的进程(这里不是se,注意跟cfs_rq的curr区分开来)
clock:运行队列的时钟,这个时钟是后面cfs,rq所使用的时钟,也是大多数proc显然的时间相关的时钟
cpu:该rq所属的cpu
leaf_cfs_rq_list:如果使用的cgroup来创建嵌套的group,那么这个group的cfs_rq通过该变量组织,注:每个cgroup都有一个cfs_rq

cfs_rq#cfs调度器类的运行队列
load:该cfs_rq的load,它只计算它本层下面的se的weight之和,并不是这个se的load,也不是递归到叶子节点上的所有se weight之和(理解这点非常重要),这里有两个概念要区分清楚:se的load与se的weight,之所以会有这两个区别是因为组调度的存在,对于一个组它本身也是一个se,它也有一个cfs_rq,所以对于组它的se->weight其实就是我们设置cgroup的cpu.shares的一个均值(cpu.shares是保存在tg->shares,而se->weight是通过update_cfs_shares计算出来的,如果它下面的se在一个cpu里,那么它们就相等,否则…还不清楚到底为什么那样算的?),而它的cfs_rq的load,则是它下面所有se的weight之和;对于普通的进程,则它本身没有cfs_rq(它有所属的cfs_rq),所以它没有cfs_rq load,只有weight
nr_running:就绪的进程数,只包括本层的(包括正在运行的)
h_nr_running:只对于组才有效,包括底层所有cfs_rq的nr_running之和
exec_lock:该cfs_rq总共占用的cpu时间(物理),只累计本层
min_vruntime:用于调整se的vruntime,它是递增的,但不一定是该cfs_rq里所有se最小
tasks_timeline:该cfs_rq的红黑树root
rb_leftmost:红黑树的最左边节点
curr:当前运行的se(对于组虽然它不会在cpu上运行,但是当它的下层有一个task在cpu上运行,那么它所在的cfs_rq就把它当做是该cfs_rq上当前正在运行的se)
rq:该cfs_rq当前所attach的cpu rq
tg:该cfs_rq所属的task group,即所属的组,通过该成员可以找到该cfs_rq对应的组在该cpu上所属的se,即该cfs_rq自身的se

sched_entity#调度实体
load:调度实体自身的load,对于普通进程这个load跟优先级成正比,优先级高的,load大,通过prio_to_weight[]表可以查找到它们的对应关系(注意与cfs_rq的load区分开)
run_node:红黑树节点
on_rq:表示是否在运行队列或正在执行(当前执行的进程是不保存在红黑树里,但它的on_rq还是标志着的,记住这个也很关键)
exec_start:这个并不是表示进程开始执行的时候,而是每次update_curr都会更新该时钟为当前rq的clock,它主要用于计算上次执行update_curr到这次再执行,总共发的cpu clock,然后再把这个差值加到sum_exec_runtime
sum_exec_runtime:进程总共执行的cpu clock(占用cpu的物理时间)
prev_sum_exec_runtime:上次该进程被调度时已经占用的cpu时间(每次在调度一个新的进程时都会把它的se->prev_sum_exec_runtime = se->sum_exec_runtime),所以sum_exec_runtime- prev_sum_exec_runtime就是这次调度占用cpu的clock
vruntime:虚拟时间(实现CFS最关键的东西),简单的理解它是执行的cpu clock的一个虚拟值,这个变换与进程的权重成反比
parent:该se的上级se(只对组调度有用)
cfs_rq:该se就绪时所属的cfs_rq,在不同cpu上该值是不一样的(即cfs_rq_of(se)找到的是se所在的父se的my_q)
my_q:该se下面的管理的se组成的cfs_rq(只对组调度有用),这个与cfs_rq的区别很重要,它是该se本身所管理的所有下级se所组成的运行队列,而cfs_rq则是该se所属的父级运行队列

task_group#组结构体,每个group都有一个task_group结构
se:该tg在每个cpu上的se
cfs_rq:该tg在每个cpu上的cfs_rq
shares:我们用cgroup设置cpu.shares的值

对于实时调度类也是一样的,它也是支持组调度的,它的运行队列是使用rt_prio_array active组织的,即bitmap+lists,我们在介绍RT类的时候再详细介绍。这些字段的含义也是proc字段的意思,所以理解这些对于理解proc信息很有帮助。

linux调度器(一)——概述相关推荐

  1. Linux调度器笔记

    相关资料 <linux 调度子系统>这个博客讲的非常好 <linux调度器源码分析 - 概述(一)>讲的也挺好,有源码分析. SCHED_FIFO等调度策略的定义和设置可以参考 ...

  2. Linux 调度器发展简述

    引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的 ...

  3. Linux 调度器内幕

    内核中这个非常重要的组件的最新版本改进了可伸缩性 M. Jones 2006 年 9 月 07 日发布 WeiboGoogle+用电子邮件发送本页面 2 本文将回顾一下 Linux 2.6 的任务调度 ...

  4. Linux调度器及CFS调度器

    Linux调度器及CFS调度器 调度器 调度器类sched_class结构体 进程的优先级 调度策略 CFS调度器 实际运行时间 虚拟运行时间 调度器结构分析 调度器 ​ 调度:就算按照某种调度的算法 ...

  5. 能感知功耗的Linux调度器(EAS)

    译者简介 白嘉庆,西邮陈莉君教授门下研一学生.曾在华为西安研究所任C++开发一职,目前兴趣是学习Linux内核网络安全相关内容. 本文的翻译宋宝华老师指导审阅. 序 2014年Linux内核峰会(Li ...

  6. Linux调度器 - deadline调度器

    一.概述 实时系统是这样的一种计算系统:当事件发生后,它必须在确定的时间范围内做出响应.在实时系统中,产生正确的结果不仅依赖于系统正确的逻辑动作,而且依赖于逻辑动作的时序.换句话说,当系统收到某个请求 ...

  7. linux调度器并发,12 Go 并发调度器模型

    一.聊聊并发这件事 在基础系列我们学习了Go的并发编程,对并发的概念已经有了一定的了解.在各种现代高级语言中,对并发的支持已经是标配,但Go的并发无论在开发效率还是在性能上都有相当的优越性.Go有什么 ...

  8. 鼠眼看Linux调度器

    一.耗子 vs Linux ? "鼠目寸光",应该是个暴光率挺高的成语了,常用来说某人看事情没有深度,看不透本质.毫无疑问,这是一个贬义100%的词.但不管是认识什么未知事物,都一 ...

  9. 鼠眼看Linux调度器 by raise_sail @ chinaunix

    来源:http://my.chinaunix.net/space.php?uid=20043340&do=blog&id=154837 /* 这是一篇4年前的文章.本人最近学习linu ...

  10. Linux进程里运行新代码,linux调度器源码分析 - 新进程加入(三)

    中专门描述了copy_process()这个创建函数,而里面有一个函数专门用于进程调度的初始化,就是sched_fork(),其代码如下 int sched_fork(unsigned long cl ...

最新文章

  1. idea控制台怎么调出来_酸汤饺子最近火了,可是酸汤是怎么调出来的?引起了网友的好奇...
  2. 课后作业-结对编程项目总结
  3. mysql resulttype_Mysql中结果集(mysql_result)与Traversable
  4. 面试总结之MISC(操作系统,网络,数学,软件开发,测试,工具,系统设计,算法)...
  5. linux安装多个mysql数据库_linux下多个mysql5.7.19(tar.gz)安装图文教程
  6. wordpress html音乐,WordPress引用百度Ting音乐方法
  7. 操作系统--多进程管理CPU
  8. 不到6年“拼”活近8亿用户 拼多多还在狂奔
  9. android控件之间的过渡动画效果,Android - 交换控件位置:基于LayoutParams的瞬间交换与基于ObjectAnimator动画效果交换...
  10. Lyft无人车战略揭秘:两个团队并行,用百度Apollo,想定行业标准
  11. 汇编:在BUFFER中定义了的十个带符号字,将其中的负数变成绝对值,并以十进制方式输出
  12. You (root) are not allowed to access to (crontab) because of pam configuration
  13. DIgSILENT出图到Matlab画图到Visio画图全过程
  14. 第二章 Maven的安装和配置
  15. 基于JavaWeb实现网上图书商城系统
  16. 【UE4笔记】Collision碰撞
  17. 深圳内推 | 香港中文大学(深圳)路广利老师招聘NLP方向研究助理
  18. gff文件_gff/gtf格式
  19. 基于matlab的眼底视网膜静脉血管分割仿真
  20. Delphi的编程语言Object Pascal(3)

热门文章

  1. javascript之querySelector和querySelectorAll
  2. python 字符串 换行_Python基础教程——字符串
  3. SpringMVC + security模块 框架整合详解
  4. 踩坑事件:windows操作系统下的eclipse中编写SparkSQL不能从本地读取或者保存parquet文件
  5. JavaScript数据结构和算法(转载)
  6. win7hosts文件位置
  7. php 用header()下载文件在firefox下没有后缀名
  8. [Spring]04_最小化Spring XML配置
  9. C#写字板问题一二 —— C#+WinForm编程趣味入门实战-天轰穿.NET4趣味编程视频教程...
  10. WinForm中窗体间的数据传递(二)