《奔跑吧linux内核》3.2笔记,不足之处还望大家批评指正

建议阅读博文https://www.cnblogs.com/openix/p/3262217.html理解linux cfs调度器

  进程大致可以分为交互式进程批处理进程实时进程。对于不同的进程采用不同的调度策略,目前Linux内核中默认实现了4种调度策略,分别是deadline、realtime、CFS和idle,分别适用struct sched_class来定义调度类。

  4种调度类通过next指针串联在一起,用户空间程序可以使用调度策略API函数(sched_setscheduler())来设定用户进程的调度策略。

问题一:请简述对进程调度器的理解,早起Linux内核调度器(包括O(N)和O(1))调度器是如何工作的?

  调度器是按一定的方式对进程进行调度的一种机制,需要为各个普通进程尽可能公平地共享CPU时间。

  O(N)调度器发布与1992年,从就绪队列中比较所有进程的优先级,然后选择一个最高优先级的进程作为下一个调度进程。每一个进程有一个固定时间片,当进程时间片使用完之后,调度器会选择下一个调度进程,当所有进程都运行一遍后再重新分配时间片。这个调度器选择下一个调度进程前需要遍历整个就绪队列,花费O(N)时间。

  O(1)调度器用于Linux2.6.23内核之前,它为每个CPU维护一组进程优先级队列,每个优先级一个队列,这样在选择下一个进程时,只要查询优先级队列相应的位图即可知道哪个队列中有就绪进程,查询时间常数为O(1)。

问题二:请简述进程优先级、nice和权重之间的关系。

  内核使用0~139的数值表示进程的优先级,数值越低优先级越高。优先级0~99给实时进程使用,100~139给普通进程使用。在用户空间由一个传统的变量nice值映射到普通进程的优先级(100~139)。

  nice值从-20~19,进程默认的nice值为0。这可以理解为40个等级,nice值越高,则优先级越低,反之亦然。(nice每变化1,则相应的进程获得CPU的时间就改变10%)。

  权重信息即为调度实体的权重,为了计算方便,内核约定nice值为0的权重值为1024,其他的nice值对应相应的权重值可以通过查表的方式来获取,表即为prio_to_weight。

问题三:请简述CFS调度器是如何工作的。

  CFS调度器抛弃以前固定时间片和固定调度周期的算法,采用进程权重值的比重来量化和计算实际运行时间。引入虚拟时钟的概念,每个进程的虚拟时间是实际运行时间相对nice值为0的权重的比例值。进程按照各自不同的速率比在物理时钟节拍内前进。nice值小的进程,优先级高且权重大,其虚拟时钟比真实时钟跑得慢,但是可以获得比较多的运行时间;反之,nice值大的进程,优先级低,权重也低,其虚拟时钟比真实时钟跑得快,获得比较少的运行时间。CFS调度器总是选择虚拟时钟跑得慢的进程,类似一个多级变速箱,nice值为0的进程是基准齿轮,其他各个进程在不同变速比下相互追赶,从而达到公正公平。

问题四:CFS调度器中的vruntime是如何计算的?

  vruntime=(delta_exec*nice_0_weight)/weight。其中,delta_exec为实际运行时间,nice_0_weight为nice为0的权重值,weight表示该进程的权重值。在update_curr()函数中,完成了该值的计算,此时,为了计算高效,将计算方式变成了乘法和移位vruntime=(delta_exec*nice_0_weight*inv_weight)>>shift,其中inv_weight=2^32/weight,是预先计算好存放在prio_to_wmult中的。

问题五:vruntime是何时更新的?

  创建新进程,加入就绪队列,调度tick等都会更新当前vruntime值。

问题六:CFS调度器中的min_vruntime有什么作用?

  min_vruntime在CFS就绪队列数据结构中,单步递增,用于跟踪该就绪队列红黑树中最小的vruntime。

问题七:CFS调度器对新创建的进程和刚唤醒的进程有何关照?

  对于睡眠进程,其vruntime在睡眠期间不增长,在唤醒后如果还用原来的vruntime值,会进行报复性满载运行,所以要修正vruntime,具体在enqueue_entity()函数中,计算公式为vruntime+=min_vruntime,vruntime=MAX(vruntime, min_vruntime-sysctl_sched_lantency/2)。

  对于新创建的进程,需要加上一个调度周期的虚拟是时间(sched_vslice())。首先在task_fork_fair()函数中,place_entity()增加了调度周期的虚拟时间,相当于惩罚,se->vruntime=sched_vslice()。接着新进程在添加到就绪队列时,wake_up_new_task()->activate_task()->enqueue_entity()函数里,se->vruntime+=cfs_rq->min_vruntime。

问题八:如何计算普通进程的平均负载load_avg_contrib?runnable_avg_sum和runnable_avg_period分别表示了什么含义?

  load_avg_contrib=runnable_avg_sum*weight/runnable_avg_period。

  runnable_avg_sum为调度实体的可运行状态下总衰减累加时间。

  runnable_avg_period记录的是上一次更新时的总周期数(一个周期是1024us),即调度实体在调度器中的总衰减累加时间。

  runnable_avg_sum越接近runnable_avg_period,则平均负载越大,表示该调度实体一直在占用CPU。

问题九:内核代码中定义了若干个表,请分别说出它们的含义,比如prio_to_weight、prio_to_wmult、runnable_avg_yN_inv、runnable_avg_yN_sum。

  prio_to_weight表记录的是nice值对应的权重值。

  prio_to_wmult表记录的是nice值对应的权重值倒转后的值inv_weight=2^32/weight。

  runnable_avg_yN_inv表是为了避免CPU做浮点计算,提前计算了公式2^32*实际衰减因子(第32ms约为0.5)的值,有32个下标,对应过去0~32ms的负载贡献的衰减因子。

  runnable_avg_yN_sum表为1024*(y+y^2+…+y^n),y为实际衰减因子,n取1~32。(实际衰减因子下图所示)

图 实际衰减因子

问题十:如果一个普通进程在就绪队列里等待了很长时间才被调度,那么它的平均负载该如何计算?

  一个进程等待很长时间之后(过了很多个period),原来的runnable_avg_sum和runable_ave_period值衰减后可能变成0,相当于之前的统计值被清0。

Linux内核——进程管理之CFS调度器(基于版本4.x)的更多相关文章

  1. Linux进程管理 (2)CFS调度器

    关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...

  2. Linux内核——进程管理与调度

    进程的管理与调度 进程管理 进程描写叙述符及任务结构 进程存放在叫做任务队列(tasklist)的双向循环链表中.链表中的每一项包括一个详细进程的全部信息,类型为task_struct,称为进程描写叙 ...

  3. Linux内核——进程管理之SMP负载均衡(基于版本4.x)

    <奔跑吧linux内核>3.3笔记,不足之处还望大家批评指正 根据实际物理属性,CPU域分类如图1所示. 图1 CPU域分类 问题一:一个4核处理器中的每个物理CPU拥有独立L1 cach ...

  4. Linux内核 ——进程管理之进程诞生(基于版本4.x)

    <奔跑吧linux内核>3.1笔记,不足之处还望大家批评指正 进程是Linux内核最基本的抽象之一,它是处于执行期的程序.它不仅局限于一段可执行代码(代码段),还包括进程需要的其他资源.在 ...

  5. linux内核 进程管理

    进程和线程 进程不单单包含可执行代码(代码段),好包含打开的文件,挂起的信号,处理器状态,虚拟内存地址等. 线程:从内核的角度来说,它并没有线程这个概念.Linux把所有线程都当做进程来实现.内核并没 ...

  6. linux内核——进程管理

    在讲进程之前先说一下进程的堆栈的吧: 1.进程的堆栈 内核在创建进程的时候,在创建task_struct的同一时候,会为进程创建对应的堆栈.每一个进程会有两个栈,一个用户栈.存在于用户空间,一个内核栈 ...

  7. CFS调度器(1)-基本原理

    首先需要思考的问题是:什么是调度器(scheduler)?调度器的作用是什么?调度器是一个操作系统的核心部分.可以比作是CPU时间的管理员.调度器主要负责选择某些就绪的进程来执行.不同的调度器根据不同 ...

  8. Linux进程管理 (7)实时调度

    关键词:RT.preempt_count.RT patch. 除了CFS调度器之外,还包括重要的实时调度器,有两种RR和FIFO调度策略.本章只是一个简单的介绍. 更详细的介绍参考<Linux进 ...

  9. 【原创】(五)Linux进程调度-CFS调度器

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

随机推荐

  1. Location replace() 方法

    replace() 方法可用一个新文档取代当前文档. <!DOCTYPE html> <html> <head> <meta charset="ut ...

  2. DBUtils学习一 增删该查

    package com.mozq.jdbc.test; import java.sql.SQLException; import java.util.List; import java.util.Ma ...

  3. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) B

    Description Kostya likes Codeforces contests very much. However, he is very disappointed that his so ...

  4. selenium登录 京东滑动验证码

    京东的滑动验证码在页面上是没有原图的,所有我是用ps把他们拼成一个的. from selenium import webdriver from selenium.webdriver import Ac ...

  5. HTML <form> 标签的 enctype

    form的enctype有三种 application/x-www-form-urlencoded 在发送前编码所有字符(默认) multipart/form-data 不对字符编码. 在使用包含文件 ...

  6. Unity Shader入门精要学习笔记 - 第8章 透明效果

    转载自 冯乐乐的 <Unity Shader入门精要> 透明是游戏中经常要使用的一种效果.在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道.当开启透明混合后,当一个物体被渲染 ...

  7. (转)Unity3D中常用的数据结构总结与分析

    http://www.cnblogs.com/murongxiaopifu/p/4161648.html#array   1.几种常见的数据结构 常碰到的几种数据结构:Array,ArrayList, ...

  8. vue axios post不能本地json

    vue 脚本架里axios post是不能本地json,GET可以 解决这个问题需要自己在node里写脚本: 在build里新建立fakedata.js var express = require(' ...

  9. 初识requestAnimationFrame

    转载地址:https://blog.csdn.net/vhwfr2u02q/article/details/79492303 核心概念: 1.CPU节能:在页面不刷新时不执行回调(页面在隐藏.最小化等 ...

  10. IE和火狐下的iframe刷新

    前面使用了前端上传插件plupload,在谷歌浏览器中运行完全没问题,但是在IE和火狐下就出现当文档加载完成之后,该文件上传的iframe插件的上传按钮点击无效,当对上传的文件进行一次删除之后,按钮就 ...