linux cfs调度器
在抽象模型中vruntime决定了进程被调度的先后顺序,在真实模型中决定被调度的先后顺序的参数是由函数entity_key决定的。
static inline s64 entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
return se->vruntime - cfs_rq->min_vruntime;
}
enqueue_task_fair---->enqueue_entity---->__enqueue_entity---->entity_key决定插入就绪队列的位置。
普通进程分为40个等级,每个等级对应一个权重值,权重值用一个整数来标示。权重值定义在数组prio_to_weight[40]中;普通进程的权重值最大为88761,最小为15。默认情况下,普通进程的权重值为1024(由NICE_0_LOAD指定)。weight是由进程的静态优先级static_prio决定的,静态优先级越高(static_prio值越小)weight值越大。普通进程的默认 nice值为0,即默认静态优先级为120,它的weight值为prio_to_weight[20],即1024。因此NICE_0_LOAD的值就 为1024。
vruntime行走速度:
系统规定:默认权重值(1024)对应的进程的vruntime行走时间与实际运行时间runtime是1:1的关系。由于vruntime的行走速度和权重值成反比,那么其它进程的vruntime行走速度都通过以下两个参数计算得到:1、该进程的权重值2、默认进程的权重值。
例如权重为3096的进程的vruntime行走速度为:1024/3096 * (wall clock)。
“真实时钟速度”即为runtime(即 wall clock)行走的速度。
进程执行执行期间周期性调度器周期性地启动,其负责更新一些相关数据,并不负责进程之间的切换:
timer_tick()---->update_process_times---->schedule_tick()
schedule_tick---->task_tick_fair---->entity_tick()---->update_curr()
update_curr()函数完成相关数据的更新。
update_curr()---->delta_exec = (unsigned long)(now - curr->exec_start)
|-->__update_curr()
|-->curr_exec_start = now;
update_curr()函数只负责计算delta_exec以及更新exec_start。其它工作由__update_curr()函数完成:
1、更新当前进程的实际运行时间(抽象模型中的runtime)。
2、更新当前进程的虚拟时间vruntime。
3、更新cfs_rq->min_vruntime。
在当前进程和下一个将要被调度的进程中选择vruntime较小的值。然后用该值和cfs_rq->min_vruntime比较,如果比min_vruntime大,则更新cfs_rq为的min_vruntime为所求出的值。
考虑下当创建新进程或者进程唤醒时,vruntime在真实模型中的处理方式:
I、新建进程
进程的ideal_time长度和weight成正比,vruntime行走速度与weight值成反比。因此当每个进程在period时间内,都执行了自己对应的ideal_time长时间,那么他们的vruntime的增量相等。而nice为0的进程的vruntime行走速度等于runtime行走速度,所以每个进程都运行它自己对应的ideal_runtime时间,其它进程的vruntime增量都等于nice值为0的进程的ideal_runtime。假设初始情况下,它们的所有进程的vruntime值都等于0,那么当一个进程运行完runtime的时间为ideal_time,那么它的vruntime将为最大,只要其它进程的运行总时间没有达到各自对应的ideal_runtime值,那么它始终排在进程队列的末尾。
对于新进程,task_fork_fair()->place_entity(cfs_rq, se, 1),其intial参数为1。新进程的vruntime值被设置为min_vruntime+sched_vslice(cfs_rq, se), sched_vslice()函数可计算出nice值为0的进程的ideal_runtime。其作用是将新加入的进程的标记为“它在period长时间内已经运行它对应的ideal_time长时间”,那么新加入进程在理论上(所有进程都执行它对应的ideal_runtime时间,没有发生睡眠、进程终止等特殊情况)只有等待period之后才能被调度。
sched_vslice(cfs_rq, se)---->calc_delta_fair(sched_slice(cfs_rq, se), se), sched_slice()计算新建进程的ideal_runtime,calc_delta_fair()将ideal_runtime转换成vruntime。
II、睡眠进程被唤醒
将进程的vruntime值设置为cfs_rq->min_vruntime值,然后再进行一下补偿:将vruntime减去与sysctl_sched_latencyd相关的一个数值。进程进入睡眠状态时cfs_rq->min_vruntime就大于或等于该进程的vruntime值,它在睡眠过程中vruntime值是不改变的,但是cfs_rq->min_vruntime的值却是单调增加的,进程醒来后补偿的量由sysctl_sched_latency给出,不管进程受到的不公平待遇大还是小,一律只补偿这么多。
真实模型总结:
a)进程在就绪队列中用键值key来排序,它没有保存在任何变量中,而是在需要时由函数entity_key()计算得出。它等于
key = task->vruntime - cfs_rq->min_vruntime
b)各个进程有不同的重要性(优先等级),越重要的进程权重值weight(task.se.load.weight)越大。
c)每个进程vruntime行走的速度和weight值成反比。权重值为1024(NICE_0_LOAD)的进程vruntime行走速度和runtime相同。
d)每个进程每次获得CPU使用权最多执行与该进程对应的ideal_runtime长时间。该时间长度和weight值成正比,它没有用变量来保存,而是需要使用sched_slice()函数计算得出。
e)ideal_runtime计算的基准是period,它也没有用变量来保存,而是由__sched_period()计算得出。
进程的优先等级决定了其权重值,task_struct中与优先级相关数据成员:
a)static_prio,指普通进程的静态优先级(实时进程没用该参数),值越小则优先级越高。静态优先级是进程启动时分配的优先级。它可以用nice()或者sched_setscheduler()系统调用更改,否则在运行期间一直保持恒定。
注意:关于a),注意本文的结尾添加的注释。
b)rt_priority,表示实时进程的优先级(普通进程没用该参数),它的值介于[0~99]之间。rt_priority的值越大其优先级越高。
c)normal_prio,由于static_prio和rt_priority与优先级的关联性不相同,因此用normal_prio统一下“单位”,统一成:normal_prio值越小则进程优先级越高。因此,normal_prio也可以理解为:统一了单位的“静态”优先级。
d)prio,在系统中使用prio判断进程优先级,prio是进程的动态优先级,其表示进程的有效优先级。对于实时进程来说,有效优先级prio就等于它的normal_prio。普通进程可以临时提高优先级,通过改变prio实现,动态优先级的提高不影响进程的静态优先级。父进程的动态优先级不会遗传给子进程,子进程的动态优先级prio初始化为父进程的静态优先级。
注:
由于在某些情况下需要暂时提高进程的优先级,因此不仅需要静态优先级和普通优先级,还需要动态优先级prio;
参考《深入Linux内核架构》p70-76、 p_288-290;
linux内核的优先级继承协议(pip)http://www.verydemo.com/demo_c167_i123862.html
进程优先级逆转问题的解决 http://blog.chinaunix.net/uid-28279855-id-3376827.html
为了在Linux中使用Priority Inheritance Protocol协议来解决优先级反转问题,Linux中引入实时互斥量rt_mutex,在task_struc结构体中也引入了pi_waiters链表,需要注意的流程为:
rt_mutex_slowlock() ----> __rt_mutex_slowlock() ---->
task_blocks_on_rt_mutex() ----> __rt_mutex_adjust_prio()
|--> rt_mutex_adjust_prio_chain()
__rt_mutex_adjust_prio调整了当前持有锁的进程的动态优先级(继承自等待队列中所有进程的最高优先级),rt_mutex_adjust_prio_chain()如果被调整的动态优先级的进程也在等待某个资源,那么也要链式地调整相应进程的动态优先级。
关于Priority Inversion可以参考《Operating System Concepts》9_ed p217-218
linux cfs调度器的更多相关文章
- linux cfs调度器_理论模型
参考资料:<调度器笔记>Kevin.Liu <Linux kernel development> <深入Linux内核架构> version: 2.6.32.9 下 ...
- linux cfs调度器_模型实现
调度器真实模型的主要成员变量及与抽象模型的对应关系 I.cfs_rq结构体 a) struct sched_entity *curr 指向当前正在执行的可调度实体.调度器的调度单位 ...
- Linux内核——进程管理之CFS调度器(基于版本4.x)
<奔跑吧linux内核>3.2笔记,不足之处还望大家批评指正 建议阅读博文https://www.cnblogs.com/openix/p/3262217.html理解linux cfs调 ...
- Linux进程管理 (2)CFS调度器
关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...
- 【原创】(五)Linux进程调度-CFS调度器
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- CFS调度器(1)-基本原理
首先需要思考的问题是:什么是调度器(scheduler)?调度器的作用是什么?调度器是一个操作系统的核心部分.可以比作是CPU时间的管理员.调度器主要负责选择某些就绪的进程来执行.不同的调度器根据不同 ...
- Linux CFS调度器之pick_next_task_fair选择下一个被调度的进程--Linux进程的管理与调度(二十八)
1. CFS如何选择最合适的进程 每个调度器类sched_class都必须提供一个pick_next_task函数用以在就绪队列中选择一个最优的进程来等待调度, 而我们的CFS调度器类中, 选择下一个 ...
- Linux CFS调度器之虚拟时钟vruntime与调度延迟--Linux进程的管理与调度(二十六)
1 虚拟运行时间(今日内容提醒) 1.1 虚拟运行时间的引入 CFS为了实现公平,必须惩罚当前正在运行的进程,以使那些正在等待的进程下次被调度. 具体实现时,CFS通过每个进程的虚拟运行时间(vrun ...
- Linux CFS调度器之负荷权重load_weight--Linux进程的管理与调度(二十五)
1. 负荷权重 1.1 负荷权重结构struct load_weight 负荷权重用struct load_weight数据结构来表示, 保存着进程权重值weight.其定义在/include/lin ...
随机推荐
- ARKit从入门到精通(10)-ARKit让飞机绕着你飞起来
1.1-ARKit物体围绕相机旋转流程介绍 1.2-完整代码 1.3-代码下载地址 废话不多说,先看效果 其实是会一直围着你转圈的,只不过笔者不好意思暴露家里的场景,所以请读者朋友们见谅~ 由于是晚上 ...
- tomcat 远程命令执行漏洞复现
影响范围 Apache Tomcat 7.0.0 - 7.0.81 不受影响的版本 Apache Tomcat 8.x Apache Tomcat 9.x 漏洞分析 在Tomcat安装目录下的配置文件 ...
- java框架篇---struts开发
1.Token Token主要是以一种指令牌的形式进行重复提交处理的,在很多情况下,如果用户对同一个表单进行了多次提交,则有可能造成数据的混乱,此时,WEB服务器必须可以对这种重复提交的行为做出处理, ...
- Z律师:创业项目如何玩转股权众筹?
原文地址:http://mt.sohu.com/20150619/n415345889.shtml 大家好,这是Z律师创业学院第一期的结业课了,正式集中的课程,就到今天为止,未来有机会,还是会不定期安 ...
- MongoDB 运行状态、性能监控,分析
这篇文章的目的是让你知道怎么了解你正在运行的Mongdb是否健康.转载自http://tech.lezi.com/archives/290 mongostat详解 启动mongodb监控,通过下面命令 ...
- 小米路由器刷Xiaomi Mi WiFi Mini openwrt
Current Stable Release - OpenWrt 18.06.1,released on August, 18th 2018. there is also PandoraBox fir ...
- 解决:According to TLD or attribute directive in tag file, attribute value does not accept any express。
http://blog.csdn.net/lzblog/article/details/22076893 ——————————————————————————————————————————————— ...
- JS DOM操作思维导图
- [技术选型] spring boot
参考博客:http://jinnianshilongnian.iteye.com/blog/1997192 官网:http://projects.spring.io/spring-boot/ 7天学会 ...
- 自然语言交流系统 phxnet团队 创新实训 个人博客 (五)
有关我们这个项目:智能自然语言交流系统,所借鉴的技术有: 第一:我们使用了科大讯飞的在线语音转换,涉及的有文本传给云端服务器的文字转换成语音和本地的语音上传给服务器转换成文字. 涉及的相关的代码有: ...