【Linux进程、线程、任务调度】三 CPU/IO消耗型进程 吞吐率/响应 SCHED_FIFO算法与SCHED_RR算法 SCHED_NORMAL算法和CFS算法 nice与renic chrt

  • 学习交流加(可免费帮忙下载CSDN资源):
  • 个人微信: liu1126137994
  • 学习交流资源分享qq群1(已满): 962535112
  • 学习交流资源分享qq群2(已满): 780902027
  • 学习交流资源分享qq群3:893215882

文章目录

    • 1、吞吐 vs. 响应
    • 2、IO消耗型 vs. CPU消耗型
    • 3、实时进程调度
    • 4、非实时进程的调度
    • 5、工具chrt和renice
    • 6、总结

上一篇文章(点击链接:【Linux进程、线程、任务调度】二)讲了:

  • fork vfork clone 的含义
  • 写时拷贝技术
  • Linux线程的实现本质
  • 进程0 和 进程1
  • 进程的睡眠和等待队列
  • 孤儿进程的托孤 ,SUBREAPER

本篇文章接着上一篇文章记录以下学习内容:

  • CPU/IO消耗型进程
  • 吞吐率 vs. 响应
  • SCHED_FIFO算法 与 SCHED_RR算法
  • SCHED_NORMAL算法 和 CFS算法
  • nice与renice
  • chrt

本篇文章主要讲解Linux系统调度器。对于调度器来说,我们需要考虑的有:吞吐与响应,CPU消耗型与IO消耗型进程。这四点都是对于调度算法的输入来说的。

同时,调度器的单位是线程,但是线程,我们知道在第一篇文章中已经讲解了,线程是一种轻量级的进程。所以本篇文章在说调度的对象时说的都是进程,但是我们要理解,线程才是调度单位。这并不矛盾!!!

1、吞吐 vs. 响应

吞吐和响应之间的矛盾

  • 响应:最小化某个任务的响应时间,哪怕以牺牲其他任务为代价
  • 吞吐:全局视野,整个系统的workload被最大化处理

首先我们在考虑调度器的时候,我们要理解操作系统的调度器设计目标追求两点:吞吐率大和延迟低。

这两点是相互矛盾的。因为吞吐率大,势必要把更多的时间放到真实有用功上而不是把时间浪费在进程上下文切换上而延迟低,势必要求优先级高的进程可以随时抢占进来,打断别人,强行插队。但是上下文切换的时间,对吞吐率来讲,本身是一个消耗。花了很多时间在上下文切换上,相当于做了很多无用功。这种消耗可以低到2us或者更低(这看起来没什么?),但是上下文切换更大的消耗不是切换本身,而是切换导致的cache miss。本身跑微博跑的好好的,现在要切换过去跑微信,CPU的cache,是很难命中微信的。

不抢占,肯定响应差,抢了又会导致吞吐率下降。

Linux系统不是一个完全照顾吞吐的系统,也不是一个完全照顾相应的的系统。它作为一个软实时系统,实际上是想达到某种平衡(后面会讲)。同时也提供给用户一定的配置能力。在内核编译的时候,Kernel Features —> Preemption Model选项实际上可以让我们编译内核的时候,是倾向于支持吞吐,还是支持响应:

越往上面选,吞吐越好,越好下面选,响应越好。服务器你一个月也难得用一次鼠标,而桌面则显然要求一定的响应,这样可以保证UI行为的表现较好。但是Linux即便选择的是最后一个选项“Preemptible Kernel (Low-Latency Desktop)”,它仍然不是硬实时的(下一篇文章讲解为何Linux系统不是一个硬实时系统)。

2、IO消耗型 vs. CPU消耗型

进程分为:IO消耗型进程与CPU消耗型进程

  • IO消耗型(狂睡,等IO资源等):CPU利用率低,进程的运行效率主要受限于I/O速度
  • CPU消耗型(狂算):多数时间花在CPU上面(做运算)

一般而言,IO消耗型任务对延迟比较敏感,应该被优先调度。它虽然时间都花在IO上,不关心CPU的性能,但是它关心的是是否能够及时的拿到CPU的使用权。也就是是否可以及时的被CPU调度。当自己完成了IO操作,但是一直不被CPU调度,那肯定也是不行的。比如,你正在疯狂编译安卓系统,而等鼠标行为的用户界面老不工作(正在狂睡),但是鼠标一点,我们应该优先打断正在编译的进程,而去响应鼠标这个I/O,这样电脑的用户体验才符合人性。

3、实时进程调度

在早期2.6内核时,调度器使用的是优先级数组和Bitmaps

  • 优先级号一共有0-139,其中0-99的是RT(实时)进程,100-139的是非实时进程。
  • 某个优先级有TASK_RUNNING进程,响应bit设置为1.
  • 调度第一个bitmap设置为1的进程。

对于Linux的RT进程,按照SCHED_FIFO和SCHED_RR的策略。

  • SCHED_FIFO:不同优先级按照优先级高的先跑到睡眠,优先级低的再跑。同等优先级的先进先出,先ready的跑到睡,后ready的接着跑。
  • SCHED_RR:不同优先级按照优先级高的先跑到睡眠,优先级低的再跑。同等优先级的进行时间片轮转。

比如Linux存在如下4个进程,T1~T4(内核里面优先级数字越低,优先级越高):

那么它们在Linux的跑法就是:
在这里插入图片描述

当然,Linux中大多数的进程都不是RT的,而是非RT的普通进程。并且,就算有RT的进程一直存在,CPU也不会一直被RT进程霸占,必须给普通进程留有一定的时间片。在Linux中存在一个RT门限。

在sched_rt_period_us时间内,RT进程最多跑sched_rt_runtime_us时间,剩下的时间必须留给非RT进程使用。

在Linux系统中上述两个时间在如下位置:
/proc/sys/kernel/sched_rt_period_us
/proc/sys/kernel/sched_rt_runtime_us

4、非实时进程的调度

4.1 早期2.6内核:

  • 在不同的优先级进行时间片轮转
  • -20 ~ 19的nice值
  • 根据睡眠情况,动态奖励和惩罚

普通进程调度,进程不会像RT进程那样一致霸占CPU,而是所有的进程都轮转获得CPU,只是当优先级高的话,可获得更多的时间片,醒来后可以抢占优先级低的进程。

但是,当进程的CPU占有率高,或者一开始的优先级高的话,后面内核会降低它的优先级,这样可以让IO消耗型的进程能够竞争过CPU消耗型的进程。
从而保障IO消耗型的进程能够及时获得CPU使用权。

4.2 CFS完全公平调度策略

新内核采用的调度策略就不是那么简单了,为了很好的统一CPU消耗型与IO消耗型进程的调度,与优先级(nice值)的协调,新内核采用了一种策略:完全公平调度策略。

注意:完全公平调度策略是针对普通进程而言的。

完全公平调度策略,内部的实现使用的是红黑树。左边节点的值小于右边节点的值。

红黑树节点的值为vruntime,进程的虚拟运行时间。

	vruntime =  pruntime * NICE_0_LOAD/ weight
  • pruntime:进程的物理运行时间,即实际的运行时间
  • weight:权重
  • NICE_0_LOAD:参数,等于1024,也是nice值为0的权重

nice值与weight值的对应关系:

CFS调度策略:

当RT进程都睡眠了(或者RT进程已经跑了超过了sched_rt_runtime_us时间值),那么就该普通进程被调度了。Linux最先调度vruntime最小的进程,也就是位于红黑树最左边的进程。假设最先调度的进程是p1,那么随着p1的运行,p1的pruntime就会变大,就会导致p1的vruntime就会变大,那么p1在红黑树中的位置就会往右移动。下一次,就会调度最新的vruntime最小的进程(最新的红黑树最左边的进程)。

那么什么样的线程最容易被调度呢?由上述公式知,当pruntime小,weight值大的时候,vruntime小,最容易被调度到。而pruntime小意味着是IO消耗型进程,weight值大的意味着是nice值小(优先级高)的进程。

这样的话,我们就可以看到,红黑树很神奇的同时照顾了普通进程的CPU/IO消耗型与优先级(nice值)的情况。

比如有4个普通进程,如下表,目前显然T1的vruntime最小(这是它喜欢睡的结果),然后T1被调度到。

pruntimeWeightvruntime
T181024(nice=0)8*1024/1024=8
T210526 (nice=3)10*1024/526=19
T3201024(nice=0)20*1024/1024=20
T420820 (nice=1)20*1024/820=24

然后,我们假设T1被调度再执行12个pruntime,它的vruntime将增大delta*1024/weight(这里delta是12,weight是1024),于是T1的vruntime成为20,那么这个时候vruntime最小的反而是T2(为19),此后,Linux将倾向于调度T2(尽管T2的nice值大于T1,优先级低于T1,但是它的vruntime现在只有19)。

所以普通进程的调度,是一个综合考虑IO/CPU消耗型与优先级的,通俗点说就是考虑你喜欢睡还是喜欢干活,以及你的nice值是多少(优先级高不高)。所以,Linux中进程的调度时间是不确定的,它具有随机性,无法判断一个进程的调度的延迟,更无法判断一个进程什么时候会被调度到,它是需要看看当前系统中是否还有其他进程在跑,以及被唤醒的进程的nice值以及它之前喜不喜欢睡觉!!!

还有一点要注意:普通进程在跑,如果突然有一个RT进程过来了,那么RT进程就是无敌的,它会被调度,直到它运行结束或者睡眠。

5、工具chrt和renice

chrt工具可以设置进程的调度策略与优先级,nice和renice可设置进程的nice值。renice是程序已经跑起来了你可以去设置nice值。

看一下程序:
two-loops.c

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>void *thread_fun(void *param)
{printf("thread pid:%d, tid:%lu\n", getpid(), pthread_self());while (1) ;return NULL;
}int main(void)
{pthread_t tid1, tid2;int ret;printf("main pid:%d, tid:%lu\n", getpid(), pthread_self());ret = pthread_create(&tid1, NULL, thread_fun, NULL);if (ret == -1) {perror("cannot create new thread");return 1;}ret = pthread_create(&tid2, NULL, thread_fun, NULL);if (ret == -1) {perror("cannot create new thread");return 1;}if (pthread_join(tid1, NULL) != 0) {perror("call pthread_join function fail");return 1;}if (pthread_join(tid2, NULL) != 0) {perror("call pthread_join function fail");return 1;}return 0;
}
  • 编译并在后天运行两份:

    $ gcc two-loops.c -pthread

在这里插入图片描述

top命令查看CPU利用率:
在这里插入图片描述

可以看到,运行的两个程序的CPU利用率都接近百分之百。

renice其中之一,再观察CPU利用率

可以很明显的看到,renice修改了进程的优先级,导致进程的CPU占有率变了。

  • 编译并在后台运行一份

在这里插入图片描述

top查看器CPU利用率接近百分之200:
在这里插入图片描述

把它所有的线程设置为SCHED_FIFO调度策略,优先级为50:

$ chrt -f  -p 50 3110
  • -f代表FIFO,-p代表进程pid 50为设置的优先级
    然后会发现进程的CPU利用率会降低一些。

当然设置调度策略(SCHED_FIFO)和RT优先级,除了可以用chrt工具,还可以直接在代码里写:
在这里插入图片描述

6、总结

掌握以下内容:

  • CPU消耗型与IO消耗型
  • 吞吐与响应的关系
  • SCHED_FIFO 与SCHED_RR调度策略
  • SCHED_NORMAL和CFS完全公平调度策略
  • nice和renice
  • chrt工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/422656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dexpress 流程图_DevExpress控件使用经验总结

DevExpress是一个比较有名的界面控件套件&#xff0c;提供了一系列的界面控件套件的DotNet界面控件。本文主要介绍我在使用DevExpress控件过程中&#xff0c;遇到或者发现的一些问题解决方案&#xff0c;或者也可以所示一些小的经验总结。总体来讲&#xff0c;使用DevExpress控…

UCenter 表结构

Ucenter 数据库表结构说明uc_admins 管理员表数据表说明&#xff1a;管理员相关信息属性说明&#xff1a;uid mediumint(8) -- 用户IDusername char(15) -- 用户名allowadminsetting tinyint(1) --allowadminapp tinyint(1) --allowadminuser tinyint(1) --allowadminbadword t…

Java学习之路整理-技术书从入门到进阶最全50+本(珍藏版 )

学习交流加 个人微信&#xff1a;LyyCoder学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff1a; 780902027一.速读一遍&#xff08;最好在1~2天内完成&#xff09; 人的大脑记忆力有限&#xff0c;在一天内快速看完一本…

问题 seata_架构设计 | 基于Seata中间件,微服务模式下事务管理

一、Seata简介1、Seata组件Seata是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA、XA事务模式&#xff0c;为用户打造一站式的分布式解决方案。2、支持模式AT 模式基于支持本地 ACID 事务的关系型数…

Override and Overload (重写和重载)

1&#xff09;方法的重写overriding和重载overloading是java多态性的不同表现. &#xff08;2&#xff09;重写overriding是父类与子类之间的多态性的一种表现&#xff0c;重载是一个类中多态性的表现。如果子类中定义方法与其父类有相同的名称和参数&#xff0c;我们说该方法被…

程序员史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)

互联网行业的特点是变化。若要提高互联网开发的技能&#xff0c;就必须跟上技术发展的步伐。埋首醉心于项目开发与实战&#xff0c;固然能够锤炼自己的开发技巧&#xff0c;却难免受限于经验与学识。 世界上并不存在速成的终南捷径&#xff0c;但阅读好的技术书籍&#xff0c;尤…

示波器1m和50欧姆示阻抗匹配_示波器输入阻抗选1MΩ还是50Ω的详细解析

熟悉示波器的朋友可能都会有过这样的困惑&#xff1a;输入阻抗有1MΩ和50Ω两种&#xff0c;我们到底该如何选择呢&#xff1f;一、传输线想要讲清楚50Ω的由来&#xff0c;我们需要先讲一下传输线。电信号实际上是以电磁波的形式在传输线中传播的。当传输线的尺寸不再远小于电…

前端学习(355):小练习

.已知两个矩形,宽高分别是200200,400400,甲矩形的坐标是x1,y1.乙矩形的坐标是x2,y2. 写出判断条件两个矩形是否相碰撞 <script>x1200;//自己随意定义坐标x2200;y1400;y2400;var boolfalse;//先定义一个布尔值为falseif(x1>x2 && x1<x2400 && y1&g…

Quartus 中快速分配器件管脚

在quartus中分配器件管脚最笨的方法是对于器件手册一个一个的敲进去&#xff0c;这样做如果用到的管脚很好还没有发觉什么不好&#xff0c;但是当用到的器件管脚很多的时候就会发现很麻烦&#xff0c;而且容易出错。接下来我来介绍一种很方便的方法。 首先在txt文档中建立管脚和…

Web前端书单从HTML到JS到AJAX到HTTP从框架到全栈

前言&#xff1a;技术书阅读方法论 一.速读一遍&#xff08;最好在1~2天内完成&#xff09; 人的大脑记忆力有限&#xff0c;在一天内快速看完一本书会在大脑里留下深刻印象&#xff0c;对于之后复习以及总结都会有特别好的作用。 对于每一章的知识&#xff0c;先阅读标题&…

自定义背景_新版快绘精选:自定义背景墙 | 吊顶 | 云渲染滤镜升级

New自定义背景墙没有合适的背景墙样板&#xff1f;你需要一个全世界独一无二&#xff0c;独属于你monent的背景墙&#xff1f;没问题&#xff01;无论是要这样↓还是这样↓快绘都能帮到你&#xff01;-- 请观看视频 --New自定义吊顶除了可以自定义背景墙&#xff0c;新版快绘也…

【C++学习详细教程目录】

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信(进微信群加)&#xff1a; LyyCoder学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027学习交…

删除开机选择系统

在我的电脑点右键--属性--高级--系统启动,系统失败和调试信息--设置--显示操作系统列表时间,和在需要时显示恢复选项的时间,在前面的小方格里打上构或去掉构就行了. 修改引导分区里面的BOOT.INI文件s C:\boot.ini 将只读属性去掉 [boot loader] timeout30 defaultmulti(0)dis…

底层知识学习记录目录表

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信(进微信群加)&#xff1a; LyyCoder学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027学习交…

cdn加载vue很慢_Vue.js 项目打包优化实践

首先上结果&#xff1a;把常用的 Vue&#xff0c;router&#xff0c;vuex&#xff0c;axios 的 runtime 包拆分了出来&#xff0c;改为 cdn&#xff1b;另外就是对于自己编写的业务代码进行分包&#xff0c;根据路由进行懒加载&#xff0c;可以较好的提高首屏加载速度。添加了全…

SharePoint 2010 网站模板要求在网站集中激活功能

从别人那里将其一个站点另存为模板&#xff0c;拷贝回来&#xff0c;上传到自己环境中的解决方案库里并激活。 然后新建站点&#xff0c;选择该模板&#xff0c;报如下错误&#xff1a; 解决方案&#xff1a; 打开在首要网站&#xff0c;网站操作---网站设置--网站集管理---网站…

C语言进阶深度学习目录表

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信(进微信群加)&#xff1a; LyyCoder学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027学习交…

一个c++ 2d图形引擎 AGG

相关站点http://www.antigrain.com/agg_docs/doc_tutorial.html 用法&#xff0c;学习中。。。 A. 这是个不错的中文介绍http://www.cnblogs.com/Kane_zzt/archive/2009/02/15/1271793.html 转载于:https://www.cnblogs.com/vilyLei/archive/2011/12/12/2284821.html

springboot 添加允许跨域_SpringBoot添加支持CORS跨域访问

CORS(Cross-Origin Resource Sharing)"跨域资源共享"&#xff0c;是一个W3C标准&#xff0c;它允许浏览器向跨域服务器发送Ajax请求&#xff0c;打破了Ajax只能访问本站内的资源限制&#xff0c;CORS在很多地方都有被使用&#xff0c;微信支付的JS支付就是通过JS向微…