[Linux] Linux 的进程如何调度——Linux的 O(1)进程调度算法

标题:[Linux] Linux 的进程如何调度——优先级与进程调度

个人主页@水墨不写bug

目录

一、前言 

二、将要出现的概念

1.进程调度队列

2.位图

3.进程的优先级

三、Linux进程的调度过程

1.活动队列(*active指向的队列)

2.过期队列(*expired指向的队列)

3.active指针和expired指针

4.总结


正文开始:


一、前言 

        当你看过书上的讲解,它通常会将操作系统对进程的调度一笔带过:

        一个一个的进程会被存储在队列中(称为运行队列),CPU通过运行队列来调度进程。

        这样的讲解通常让人捉摸不透,Linux操作系统具体是怎么调用进程的?又是怎么一个调用法?能不能用直观的图来表示这样的调度过程?这就是本文着重讲解的内容。

二、将要出现的概念

1.进程调度队列

        Linux中,每个CPU都对应有一个运行队列CPU与运行队列是一对一的关系。CPU想要调度进程,就需要到runqueue这个数据结构中去得到进程的PCB:task_struct

         在这里,我们形象的表示出runqueue:

         在runqueue中,由于不考虑其他的信息,只考虑进程调度相关的变量,我们仅仅在上面的图形中表示出了进程调度的关键信息。首先我们会发现,红色和蓝色分别是两组相同的结构,这与调度的逻辑密切相关。

        这两组相同的结构,一组表示正在被调度的进程队列,另一组是未被调度的进程队列这里的队列(queue)要与运行队列(runqueue)区分,这里的队列的实际类型是:

struct task_struct *queue[140];

        运行队列是一个CPU调度对应的一个数据结构,但是这里的队列只是运行队列中的一个组织进程的数据结构。

2.位图

        在C++中,位图(bitmap)通常指的是一种用于表示和操作位(bit)的数据结构。位图可以被看作是一个由连续的位(0或1)组成的序列,其中每一个位都可以表示某个状态或属性的值

        在C++中,可以使用位操作(bit manipulation)来对位图进行操作,例如设置某个位的值、获取某个位的值、将多个位进行逻辑运算等。常见的位操作操作符包括位与(&)、位或(|)、位异或(^)、位取反(~)等。

        使用位图可以实现一些高效的算法和数据结构,例如位图可以被用来表示一个大范围的二进制数,节省内存空间。位图也可用于表示布尔值数组、位向量(bit vector)、位集合(bit set)等数据结构。

        在我们上述的两个相同的结构中,都有一个位图bitmap[5]:

int bitmap[5];

         int具有32位,可以表示32个状态值,5个int则可以表示160个状态值,正好可以覆盖140个大小的PCB数组用位图表示PCB数组的这个位置上是否有进程。实际上PCB数组内存储的是一个task_struct*的链表,在具体调用时,如果这个位置上有链表,则取出头节点,加载到CPU中调度。

        我们首先需要知道,Linux操作系统想要正常为用户服务,就需要不断的调度用户的进程,所以调度进程是一个每时每刻都在发生的事。想要调度进程,Linux就需要在进程队列中查找进程。运行队列是一个指针数组,每一个位置只可能有两种状态:

        1)存储有有效的进程地址;

        2)空指针;

        这就需要一个非常高效的确认进程队列中每一个位置是否有进程的查找方法——这也就是在这里位图的用武之地:

        我们可以通过访问表示位图数组的每一个元素,每一个元素是整形,表示32个位置是否有指针存在:这样我们就可以通过一次判断,就可以知道32个位置是否有进程了!!!

3.进程的优先级

        在Linux操作系统中,优先级是相对于拥有时间片的进程而言的。进程分为实时进程和分时进程,分时进程才有时间片的概念,并会被根据优先级依次被操作系统调度。

        上述的140个数组位置而言:

         普通优先级: 100~ 139(我们创建的进程一般普通的优先级,想想nice值的取值范围,可与之对应!)

        实时优先级: 0~ 99(在这里我们不关心)

        除此之外,如果你优先级不太了解, 可参考 (《进程的优先级》)。

        我们在之前的讲解中,我们明白了这样的一个事实:CPU是稀缺资源,相对于CPU的数目来说,进程的数目是更多的,进程的调度需要CPU,于是进程需要竞争CPU资源,这也就需要指定进程优先级。

        进程的优先级与操作系统的尽量让每个进程调度的总时间是相同的原则是不冲突的,在本文的第三部分会有详尽的演示。

三、Linux进程的调度过程

 

1.活动队列(*active指向的队列)

时间片还没有结束的所有进程都按照优先级放在该队列;

        nr_active: 表示总共有多少个运行状态的进程;

        queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级!

从该结构中,选择一个最合适的进程,过程是怎么的呢?

        1. 从0下表开始遍历queue[140]

        2. 找到第一个非空队列,该队列必定为优先级最高的队列

        3. 拿到选中队列的第一个进程,开始运行,调度完成!

        4. 遍历queue[140]时间复杂度是常数!但还是太低效了!

        bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个比特位表示队列是否为空,这样,便可以大大提高查找效率

2.过期队列(*expired指向的队列)

过期队列和活动队列结构一模一样;

过期队列上放置的进程,都是时间片耗尽的进程;

当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算;

 

3.active指针和expired指针

        active指针永远指向活动队列

        expired指针永远指向过期队列

        可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。

        为了解决这个问题,操作系统会在合适的时候交换两个指针的内容,这样就完成了操作系统对进程的调度的可持续进行

 

        由于查找进程的顺序是从小下标到大下标查找的,这也就导致了优先级数值比较小的进程会优先被调用,但是终究是要在这个进程队列调度完成之后才能进行下一轮进程进程调度,这就很好的体现了优先级的意义:优先级高,体现在每个调度周期中先调度这个优先级高的进程。

4.总结

        在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增加,我们称之为进程调度O(1)算法。


完~

未经作者同意禁止转载 

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

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

相关文章

LeetCode[中等] 763. 划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 思路 贪心…

Centos 7.9 Kubeadm安装k8s1.20.11

一、环境 主机用途192.168.76.140k8s-master1192.168.76.141k8s-node1 二、设置yum源 由于系统已经关闭,可以用centos9尝试 cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak vi /etc/yum.repos.d/CentOS-Base.repo# 使用阿里云的y…

【动态规划-分组背包】【hard】力扣2218. 从栈中取出 K 个硬币的最大面值和

一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。 每一次操作中,你可以从任意一个栈的 顶部 取出 1 个硬币,从栈中移除它,并放入你的钱包里。 给你一个列表 piles ,其中 piles[i] 是一个整数数组,分…

FOC电机驱动开发踩坑记录

关键技术 SVPWM电机磁场控制电流采样park变换和Clark变换滑膜观测器(无感FOC) SVPWM电机磁场控制 SVPWM主要思想是通过精确的对UVW三相电流的分时控制,来控制转子的合成力矩,达到目标方向,常用的是6分区的设计&…

浅谈汽车智能座舱如何实现多通道音频

一、引言 随着汽车智能座舱的功能迭代发展,传统的 4 通道、6 通道、8 通道等音响系统难以在满足驾驶场景的需求,未来对于智能座舱音频质量和通道数会越来越高。接下来本文将浅析目前智能座舱如何实现音频功放,以及如何实现多路音频功放方案。…

C语言+单片机

今天内容有点水哈哈&#xff08;忙着练焊铁技术了嘻嘻&#xff09; C语言 简单学习了while语言以及其与for语言的区别和适用方法 .循环结构&#xff1a; 初始化语句条件判断句条件控制句 for语句 for(int1;i<100;i){执行条件} for (int i 1; i < 100; i) {printf(&quo…

leetcode每日一题day22(24.10.2)——准时到达的列车最小时速

思路&#xff1a;这种在有约束条件情况下&#xff0c;求最值或最符合要求的情况&#xff0c;首先是很容易想到&#xff0c;从时速为1开始往后找找到满足条件就输出&#xff0c;但这无疑工程量很大&#xff0c;每种可能的速度都要对列车数组进行遍历&#xff0c; 时间复杂度为C…

Stable Diffusion绘画 | 来训练属于自己的模型:LoRA模型验收

我们每次训练出来的模型&#xff0c;一般都会生成 20-30 个&#xff0c;至于哪个模型符合要求&#xff0c;较为理想呢&#xff1f; 接下来需要对每个 LoRA模型 进行逐一对比测试。 为了测试模型的泛化性&#xff0c;可选择使用一些较为特殊的提示词&#xff0c;看看各个模型对…

828华为云征文 | 云服务器Flexus X实例:向量数据库 pgvector 部署,实现向量检索

目录 一、什么是向量数据库 pgvector &#xff1f; 二、pgvector 部署 2.1 安装 Docker 2.2 拉取镜像 2.3 添加规则 三、pgvector 运行 3.1 运行 pgvector 3.2 连接 pgvector 3.3 pgvector 常见操作 四、总结 本篇文章通过 云服务器Flexus X实例 部署向量数据库 pgve…

安卓13默认使用大鼠标 与配置分析 andriod13默认使用大鼠标 与配置分析

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 android13里面的鼠标貌似比以前版本的鼠标小了,有些客户想要把这个鼠标改大。这个功能,android有现成的,就在这里,设置 =》无障碍 =》色彩和动画 =》 大号鼠标指针。 我们通过…

Spring注解系列 - @Autowired注解

文章目录 使用总结注入原理Autowired 注入过程InjectionMetadataInjectedElement依赖注入查找过程findAutowireCandidates 缓存注入信息 Resource 注解 使用总结 Autowired注解可以自动将所需的依赖对象注入到类的属性、构造方法或方法中&#xff0c;从而减少手动注入依赖的代…

ubuntu 设置静态IP

一、 ip addresssudo nano /etc/netplan/50-cloud-init.yaml 修改前&#xff1a; 修改后&#xff1a; # This file is generated from information provided by the datasource. Changes # to it will not persist across an instance reboot. To disable cloud-inits # ne…

【重学 MySQL】五十、添加数据

【重学 MySQL】五十、添加数据 使用INSERT INTO语句添加数据基本语法示例插入多行数据注意事项 使用LOAD DATA INFILE语句批量添加数据其他插入数据的方式注意事项 在MySQL中&#xff0c;添加数据是数据库操作中的基本操作之一。 使用INSERT INTO语句添加数据 使用 INSERT IN…

单链表的增删改查(数据结构)

之前我们学习了动态顺序表&#xff0c;今天我们来讲一讲单链表是如何进行增删改查的 一、单链表 1.1、单链表概念 概念&#xff1a;链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 1.2、链表与顺序表的…

python的几个基本数据类型及其相关操作(字符串str,元组tuple,列表list,字典dict)

一、str及其相关操作 1、字符串的基本方法 字符串的索引、获取字符串长度、利用index获取索引位置&#xff0c;统计某字符在字符串中出现的次数。用法如下方代码。 python的变量在创建时不需要声明其数据类型&#xff0c;他会自动识别变量后的数据类型&#xff0c;所以创建一…

(undone) 阅读 MapReduce 论文笔记

参考&#xff1a;https://pdos.csail.mit.edu/6.824/papers/mapreduce.pdf 摘要&#xff1a;简单介绍了 MapReduce 是在大型分布式系统上工作的 Introduction 的内容总结&#xff1a; 1.介绍背景&#xff1a;为什么我们需要分布式系统&#xff1f;MapReduce 的意义是哪些 2.简…

运动耳机哪个牌子的好?5大质量不凡的运动耳机测评力荐!

在快节奏的生活中&#xff0c;无论是晨跑、健身还是户外探险&#xff0c;音乐都成了许多人不可或缺的陪伴。运动耳机&#xff0c;作为一种专为运动场景设计的音频设备&#xff0c;旨在提供高质量音频体验的同时&#xff0c;保证佩戴的舒适度和运动的安全性。 &#xff08;上图为…

YOLOv11改进 | 主干篇 | YOLOv11引入MobileNetV4

1. MobileNetV4介绍 1.1 摘要&#xff1a; 我们推出了最新一代的 MobileNet&#xff0c;称为 MobileNetV4 (MNv4)&#xff0c;具有适用于移动设备的通用高效架构设计。 在其核心&#xff0c;我们引入了通用倒瓶颈&#xff08;UIB&#xff09;搜索块&#xff0c;这是一种统一且…

小川科技携手阿里云数据库MongoDB:数据赋能企业构建年轻娱乐生态

随着信息技术的飞速发展&#xff0c;企业在处理海量数据时所面临的挑战日益严峻。特别是在年轻娱乐领域&#xff0c;用户行为的多样性和数据量的激增对数据存储与分析技术提出了更高的要求。在此背景下&#xff0c;小川凭借其前瞻性的技术视野&#xff0c;选择了MongoDB作为其数…

AlmaLinux 9 安装mysql8.0.38

文件下载 https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.39-linux-glibc2.12-x86_64.tar 选择合适系统版本 下载后解压 tar -xvf mysql-8.0.39-linux-glibc2.12-x86_64.tar解压后里面有三个文件夹 使用mysql-8.0.39-linux-glibc2.12-x86_64.tar.xz即可&#xff0c…