Linux-进程调度器

1. 前言 

        在计算机中,进程的数量远多于cpu的数量,所以就存在,多个进程抢占一个cpu的情况,所以就需要一套规则,决定这些进程被处理的顺序,这就叫做进程调度。

        在我的简单理解下,其实就是把进程放在一个队列中,cpu挨个去执行,但是后面知道了进程具有并发性,其实就是,一个cpu在某一时刻,只能处理一个进程,但是cpu并不会处理完这个进程,而是处理很短的时间(毫秒级别), 进程在cpu上跑的时间段,我们称之为时间片。不论处理的怎么样,结束没结束不重要,接着处理下一个,这个进程中间的上下文数据被保存到进程PCB中,然后去排队吧。

5e0106a7c5b34d41b826fee154b7e028.png

        这就是并发,虽然在某一时刻,我只在处理一个任务,但是在一个时间段,我就相当于同时处理多个任务。这些任务是被同步推进的。

        后面还有进程优先级的概念,就相当于在排队,但是你VIP你就可以按照规则排在前面。

        但是对于cpu而言,他只是负责计算,至于这些进程的优先级处理我并不关心,我只想要知道下一个进程是谁。那进程排序的规则是什么,又是谁来维护呢?

2. 进程调度器

        进程调度器,它负责计算并决定一个进程何时获取CPU时间以及占用CPU的时长。

a74bb365b5b44fefaf7a5b9bc763cb7d.png

        不要害怕,这些是我总结的大部分内容的结构图 ,接下来我会一一介绍这些

        你应该看到了,进程调度器在最上面,和cpu交互的那个sched_class,Linux设计的一个结构体类型,里面定义了很多抽象的接口(函数指针)。

struct sched_class{
    // 链表
    const struct sched_class* next; 

    // 向运行队列添加一个进程
    void(*enqueue_task)(struct rq* rq, struct task_struct* p, int flags);

    // ...
    
    // 挑选下一个优先级更高的进程
    struct task_struct(*pick_next_task)(struct rq* rq, struct task_struct* prev, struct rq_flags* rf);
}

 enqueue_task:向运行队列中插入一个进程

 pick_next_task:从运行队列中挑选下一个优先级更高的进程

        里面类似的函数指针还有很多,实现不同的功能。其次调度器其实是一个链表。进程通用调度器提供了一个模板,调度类其实就是这些类型的实现,以及对这些接口的实现。

3. 进程调度类

        为什么要实现这么多的调度类呢,因为不同的使用场景:

  • stop调度类,是系统内核线程所使用,用户不能使用,优先级最高,任务一但被执行,它将不能被抢占,不能被切换,其将一直执行下去,直至进程执行完或主动让出cpu。         
  • 截止日期(dl)调度类,这个任务有最后期限,必须在任务最后期限之前完成,例如播放视频,一秒钟60帧的视频,大概每16毫秒就要播放一帧画面,这个就是最后期限
  • 实时(rt)调度类,需要立马执行的任务,需要具有实时的特性,就像驾驶系统的刹车任务,必须要实时响应
  • 完全公平(fair)调度类,这些任务都是完全公平的接受“相同”的时间,这个时间其实是虚拟时间,后面会说
  • 空闲(ide)调度类,没有其他进程需要执行,就轮到它了

        因为每个调度类都有自己的排序规则,所以Linux就使用这种设计:第一层,定义结构体类型,定义抽象的操作接口,比如向运行队列插入一个任务,从运行队列中挑选一个任务;第二层,调度类,根据自身类的特点,实现具体的操作。

         通过这样两层,调度器可以从每个调度类的细节实现中抽离出来

4. 进程运行队列

        运行队列,顾名思义,运行队列...

        调度类,是方法的实现,你需要插入任务啊,还是删除任务,还是选择任务,这些方法都可以通过调度类的函数方法实现,但是没有数据只有方法肯定是不行的。

        运行队列,其实就是对各个进程的通过数据结构管理起来,简而言之存放进程的地方

5cff9994499a4b16bd1d9ad1cfa2f8af.png

        不同的调度类,需要不同的数据结构来进行管理,所以就出现了不同的运行队列,例如实时调度类就要有先进先出队列,环形队列。截止日期调度类和完全公平调度类依赖的数据结构都是红黑树。 

5. 进程调度过程

        进程的调度是从调用通用调度器开始的,kernel/sched/core.c中定义的schedule()函数。该函数的功能是挑选下一个最佳的可运行任务。schedule()函数中的pick_next_task()遍历调度类中包含的所有对应的函数,并最终选出要运行的下一个最佳任务。        

---摘自《精通Linux内核开发》

c31f3b032dfa4a219c1c0fdd99af6013.png

        prev是一个task_struct*类型的指针,task_struct内部包含一个sched_class*类型的指针,指向该进程属于的调度类。 

6. CFS完全公平调度类(浅谈)

        CFS,这里主要谈谈以下三点:虚拟运行时间(vruntime),权重计算,红黑树排序

        前面两个主要是为了CFS的公平和优先级,最后一个决定运行队列的数据结构

        如何能够保证在这个类中的所有进程都是完全公平的接受cpu的调度呢,但是还有优先级。你一听,这不是互相矛盾嘛,又要公平,又要有优先级。确实矛盾。但是没办法,就是在有优先级的情况下实现公平。

        如果只要公平,那就每个进程都运行相同的时间,如果要优先级,那就你先我后,但是你忘记并发了嘛,必须要每一个进程都要上去跑一会。

        所以虚拟运行时间(vruntime)和权重计算就是这么来的。

        每一个进程都有一个真实运行时间和虚拟运行时间,真实运行时间,就是你真实在cpu上跑了多少毫秒,vruntime其实是根据真实运行时间和优先级权重的权重计算而来的,然后再红黑树中按照vruntime来进行排序。每次pick_next_task都会选择红黑树最左端的进程。

        nice值标识进程的优先级,nice值每减少1,CPU的时间片会增加10%

        例如:一个A进程nice值为0,另一个B进程nice值为1,假如A进程的时间片是10ms,它也真实跑了10ms,那么他的vruntime就会加10,而B进程时间片是11ms,它也真实跑了11ms,但是根据权重计算,它的vruntime只会加10.由此实现完全公平。

7. 实时调度类(浅谈)

        实时调度类,它的运行队列的数据结构是带头双向链表。

        它有两种调度策略:

SCHED_FIFO(先进先出实时调度策略)

        进程一旦获得CPU执行权,就会一直运行下去,直到该进程自愿放弃CPU,实时进程按照优先级队列排序

SCHED_RR(轮转实时调度策略)

        进程在执行完一个时间片后,即使没有完成任务,也会被迫让出CPU给同一优先级的其他进程,同一优先级的实时进程能够实现时间片的轮转,确保在紧迫性相同的情况下公平分配CPU时间

8. 总结

        Linux内核的知识非常多,对于进程调度这一块内容有很多,这篇博客只能带大家揭开内核神秘面纱的一角,希望大家有所收获。

        关于进程调度器的代码啊,我建议大家可以看看这篇博客:http://t.csdnimg.cn/ORcS7

完 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

普乐蛙景区vr体验馆VR游乐场设备身历其境体验

小编给大家推荐一款gao坪效产品【暗黑战车】,一次6人同乘,炫酷外观、强大性能和丰富内容适合各个年龄层客群,紧张刺激的VR体验让玩家沉浸在元宇宙的魅力中,无论是节假日还是平日,景区商场助力门店提高客流量和营收~ ◆…

实验三 .Java 语言继承和多态应用练习 (课内实验)

一、实验目的 本次实验的主要目的是通过查看程序的运行结果及实际编写程序,练习使用 Java 语言的继承特性。 二、实验要求 1. 认真阅读实验内容,完成实验内容所设的题目 2. 能够应用多种编辑环境编写 JAVA 语言源程序 3. 认真体会多态与继承的作用…

B+树详解与实现

B树详解与实现 一、引言二、B树的定义三、B树的插入四、B树的删除五、B树的查找效率六、B树与B树的区别和联系 一、引言 B树是一种树数据结构,通常用于数据库和操作系统的文件系统中。它的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间…

WebGL/Cesium 大空间相机抖动 RTE(Relative to Eye)实现原理简析

在浏览器中渲染大尺寸 3D 模型:Speckle 处理空间抖动的方法 WebGL/Cesium 大空间相机抖动 RTE(Relative to Eye)实现原理简析 注: 相机空间和视图空间 概念等效混用 1、实现的关键代码 const material new THREE.RawShaderMaterial({uniforms: {cameraPostion: {…

【Qt QML】用CMake管理Qt工程

CMake是一个开源、跨平台的工具系列,用于构建、测试和打包软件。CMake使用简单的独立配置文件来控制软件编译过程。与许多跨平台系统不同,CMake被设计为与本地构建环境结合使用。 下面我们在CMake项目中使用Qt的最基本方法。首先,创建一个基本…

如何解决pycharm创建项目报错 Error occurred when installing package ‘requests‘. Details.

🐯 如何解决PyCharm创建项目时的包安装错误:‘requests’ 🛠️ 文章目录 🐯 如何解决PyCharm创建项目时的包安装错误:requests 🛠️摘要引言正文📘 **问题分析**🚀 **更换Python版本…

OpenCV 实现重新映射(53)

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV 实现霍夫圆变换(52) 下一篇 :OpenCV实现仿射变换(54) 目标 在本教程中,您将学习如何: 一个。使用 OpenCV 函数 cv::remap 实现简…

Java Web 开发 - 掌握拦截器和监听器

目录 深入了解Java Web的拦截器和监听器 拦截器(Interceptor) 拦截器的使用场景 拦截器实例 思维导图 ​编辑 监听器(Listener) 监听器的使用场景 监听器类型 监听器实例 思维导图​编辑 总结 深入了解Java Web的拦截器…

C——双向链表

一.链表的概念及结构 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。什么意思呢?意思就是链表在物理结构上不一定是连续的,但在逻辑结构上一定是连续的。链表是由一个一个的节点连…

uniapp0基础编写安卓原生插件和调用第三方jar包和编写语音播报插件之使用jar包插件

前言 如果你不会编写安卓插件,你可以先看看我之前零基础的文章(uniapp0基础编写安卓原生插件和调用第三方jar包和编写语音播报插件之零基础编写安卓插件), 我们使用第三方包,jar包编写安卓插件 开始 把依赖包,放到某个模块的/libs目录(myTestPlug/libs) 还要到build…

java-函数式编程-函数对象

定义 什么是合格的函数?无论多少次执行函数,只要输入一样,输出就不会改变 对象方法的简写 其实在类中,我们很多参数中都有一个this,被隐藏传入了 函数也可以作为对象传递,lambda就是很好的例子 函数式接口中…

ROS实操:通信机制的实现

最近闲来无事,打算重温了一下ROS方面的相关知识。先前的学习都是一带而过,发现差不多都忘了,学习的不够深入。因此,在重温的同时,写下了这篇关于ROS架构的学习博客。 上一篇博客的链接为:ROS架构的学习【No…

如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响

原文链接:如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247602528&idx6&snc89e862270fe54239aa4f796af07fb71&chksmfa82…

visio画图基本用法

添加图形 点击上面的箭头 添加一些基本的形状 添加连接点 点击这个 X 按住Ctrl,在想要的位置上添加连接点 更改线条样式 选中线条之后,右键 可以选择箭头样式 添加文本框 visio对象复制到word里面,画布存在大量空白问题 https://blog.…

【C语言】深入了解文件:简明指南

🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 一、文件的概念1.1 文件名:1.2 程序文件和数据文件 二、数据文…

如何利用MCU自动测量单元提高大坝安全监测效率

大坝作为重要的水利基础设施,其安全性直接关系到人民群众的生命财产安全和社会的稳定发展。因此,对大坝进行实时、准确的安全监测至关重要。近年来,随着微控制器单元(MCU)技术的不断发展,其在大坝安全监测领域的应用也越来越广泛。…

数据结构——排序算法分析与总结

一、插入排序 1、直接插入排序 核心思想:把后一个数插入到前面的有序区间,使得整体有序 思路:先取出数组中第一个值,然后再用tmp逐渐取出数组后面的值,与前面的值进行比较,假如我们进行的是升序排序&…

操作系统的运行机制详解

操作系统的 运行机制 #mermaid-svg-jVBbLUJa6gITOo7L {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jVBbLUJa6gITOo7L .error-icon{fill:#552222;}#mermaid-svg-jVBbLUJa6gITOo7L .error-text{fill:#552222;stroke…

C 深入指针(1)

目录 一、const 1、const修饰变量 2、const修饰指针 2.1 const int* p(int const* p) 2.2 int* const p 2.3 结论 二、指针运算 1、指针 - 整数 2、指针 - 指针 3、指针的关系运算 三、指针的使用 1、模拟实现 strlen 2、传值调用和传址调用…

安装VMware Tools报错处理(SP1)

一、添加共享文件 因为没有VMware Tools,所以补丁只能通过共享文件夹进行传输了。直接在虚拟机的浏览器下载的话,自带的IE浏览器太老了,网站打不开,共享文件夹会方便一点,大家也可以用自己的方法,能顺利上…
最新文章