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.rhkb.cn/news/317862.html

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

相关文章

Docker 安装部署 postgres

Docker 安装部署 postgres 1、拉取 postgres 镜像文件 [rootiZbp19a67kznq0h0rgosuxZ ~]# docker pull postgres:latest latest: Pulling from library/postgres b0a0cf830b12: Pull complete dda3d8fbd5ed: Pull complete 283a477db7bb: Pull complete 91d2729fa4d5: Pul…

【docker】Docker开启远程访问

将构建的镜像自动上传到服务器。 需要开放 Docker 的端口,让我们在本地能连接上服务器的 Docker,这样,才能上传构建的镜像给 Docker。 开启远程访问 首先在服务器打开 Docker 的服务文件 vim /usr/lib/systemd/system/docker.service修改…

android studio项目实战——备忘录(附源码)

成果展示&#xff1a; 1.前期准备 &#xff08;1&#xff09;在配置文件中添加权限及启动页面顺序 ①展开工程&#xff0c;打开app下方的AndroidManifest.xml,添加权限&#xff0c;如下&#xff1a; <uses-permission android:name"android.permission.CAMERA"…

OpenHarmony开源软件供应链安全风险

慕冬亮&#xff0c;华中科技大学网络空间安全学院副教授&#xff0c;武汉英才&#xff0c;华中科技大学OpenHarmony技术俱乐部、开放原子开源社团指导教师。研究方向为软件与系统安全&#xff0c;在国际安全会议上发表十余篇论文&#xff0c;并获得ACM CCS 2018杰出论文奖。创立…

Grafana页面嵌入自建Web应用页面

目录 一、应用场景 二、实现方式 1、修改Grafana配置文件 2、获取监控页面url 3、隐藏左侧和顶部菜单 一、应用场景 需要将Grafana监控页面嵌入自建Web应用页面&#xff0c;使Grafana监控页面成为自建Web应用的一部分。 二、实现方式 总体思路&#xff1a;修改Grafana配…

【R语言数据分析】基本运算与数据导入速查

R语言中命名可以包含英文字母&#xff0c;下划线&#xff0c;数字&#xff0c;点&#xff0c;下划线和数字不能作为名字的开头&#xff0c;点可以开头&#xff0c;但是点开头后面不能跟数字。一般的命名就是只使用英文和下划线就够了。 四则运算 R语言的除法是即使给的两个数…

展会资讯 | 现场精彩回顾 阿尔泰科技参展2024第23届中国国际(西部)光电产业!

2024第23届中国国际&#xff08;西部&#xff09;光电产业博览会&#xff0c;在成都世纪城新国际会展中心圆满落幕&#xff01;来自各地的光电领域设备及材料厂商汇聚一堂&#xff0c;展示前沿技术及创新成果。 展会现场&#xff0c;来自全国各地的500余家企业就精密光学、信息…

进迭时空宣布开源RISC-V芯片的AI核心技术

仟江水商业电讯&#xff08;4月29日 北京 委托发布&#xff09;4月29日&#xff0c;在“创芯生生不息——进迭时空2024年度产品发布会”上&#xff0c;进迭时空CEO、创始人&#xff0c;陈志坚博士宣布将开源进迭时空在自研RISC-V AI CPU上的核心技术&#xff0c;包括AI扩展指令…

C语言/数据结构——每日一题(合并两个有序链表)

一.前言 嗨嗨嗨&#xff0c;大家好久不见&#xff01;今天我在LeetCode看到了一道单链表题&#xff1a;https://leetcode.cn/problems/merge-two-sorted-lists想着和大家分享一下&#xff0c;废话不多说&#xff0c;让我们开始今天的题目分享吧。 二.正文 1.1题目描述 1.2题…

智慧旅游驱动行业革新:智能技术引领服务全面升级,匠心打造高品质、个性化旅游新体验

一、引言 随着科技的飞速发展和信息化程度的不断提高&#xff0c;智慧旅游正逐渐成为旅游业发展的新趋势。智慧旅游&#xff0c;顾名思义&#xff0c;是以智能化技术为支撑&#xff0c;通过大数据、云计算、物联网、人工智能等先进技术的应用&#xff0c;实现旅游服务的全面升…

袁庭新ES系列17节|Spring Data Elasticsearch基础

前言 为了简化对Elasticsearch的操作Spring Data提供了Spring Data Elasticsearch。Spring Data Elasticsearch是Spring Data技术对Elasticsearch原生API封装之后的产物&#xff0c;它通过对原生API的封装&#xff0c;使得程序员可以简单的对Elasticsearch进行各种操作。接下来…

HarmonyOS 4.0(鸿蒙开发)01 - 怎么学习鸿蒙引导篇

作为公司的全栈开发工程师 以及 未来的发展是有鸿蒙这个阶段的&#xff0c;以及本身具有这个技术栈由此后续会分享自己在实战中学习到的东西&#xff0c;碰到的bug都会分享出来&#xff0c;这是引导篇期待后续的更新 学习目标&#xff1a; 理解HarmonyOS操作系统的架构和开发…

Javascript:Web APIs(一)

Javascript基础&#xff08;一&#xff09; Javascript基础&#xff08;二&#xff09; Javascript基础&#xff08;三&#xff09; Javascript基础已经结束&#xff0c;接下来我们将进入到整个Web API学习中&#xff0c;在此&#xff0c;我们将学习DOM操作&#xff0c;基本的…

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

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

IGM焊接机器人RTE 495伺服电机维修详情一览

在当今科技迅速发展的时代&#xff0c;机器人已成为各行各业不可或缺的重要工具。IGM机器人便是其中之一&#xff0c;其工业机械手伺服马达作为机器人的关键部件&#xff0c;确保机器人能够高效、稳定地运行。当出现IGM焊接机器人RTE 495伺服电机故障问题时&#xff0c;及时进行…

Android 文件传输

目录 device explorer 文件目录关系对应&#xff1a; device explorer 经常写adb命令传文件&#xff0c;结果发现Android studio有自带的文件管理器&#xff0c;可以上传下载文件。 tool windows ->device explorer 文件目录关系对应&#xff1a; Android java获取的程序…

【华为】路由综合实验(基础)

【华为】路由综合实验 实验需求拓扑配置AR1AR2AR3AR4AR5PC1PC2 查看通信OSPF邻居OSPF路由表 BGPBGP邻居BGP 路由表 配置文档 实验需求 ① 自行规划IP地址 ② 在区域1里面 启用OSPF ③ 在区域1和区域2 启用BGP&#xff0c;使AR4和AR3成为eBGP&#xff0c;AR4和AR5成为iBGP对等体…

Vitis HLS 学习笔记--S_AXILITE 寄存器及驱动

目录 1. 简介 2. S_AXILITE Registers 寄存器详解 2.1 “隐式”优势 2.2 驱动程序文件 2.3 硬件头文件 2.4 硬件头文件中 SC/COR/TOW/COH 的解释 2.5 驱动控制过程 3. 总结 1. 简介 回顾此博文《Vitis HLS 学习笔记--Syn Report解读&#xff08;1&#xff09;-CSDN博…

嘉楠堪智 CanMV K230 的 CanMV-IDE 环境与 MicroPython 编程

嘉楠推出了 CanMV IDE 开发环境&#xff0c;可以使用 MicroPython 开发针对 CanMV K230 的各种程序&#xff0c;同时也提供了大量的例子程序&#xff0c;方便使用者学习。 嘉楠开发者社区&#xff0c;给出了详细的 CanMV K230 教程&#xff0c;可以借以快速上手。 目录 固件…

商务谈判模拟口才训练方案(3篇)

商务谈判模拟口才训练方案&#xff08;3篇&#xff09; 商务谈判模拟口才训练方案&#xff08;一&#xff09; 一、训练目标 本训练方案旨在提高参与者在商务谈判中的口才表达能力&#xff0c;包括清晰表达、有效倾听、应对挑战和构建信任等能力。 二、训练内容 基础口才训练…