Linux相关概念和重要知识点(11)(进程调度、Linux内核链表)

news2024/12/25 0:14:50

1.Linux调度算法

上篇文章我粗略讲过queue[140]的结构,根据哈希表,我们可以将40个不同优先级的进程借助哈希桶链入queue[140]中。调度器会根据queue的下标来进行调度。但这个具体的调度过程是怎样的呢?以及runqueue和queue[140]的关系是什么?我们需要更深入了解

(1)queue

PCB* queue[140]只是一个成员变量,它存在于另一个结构体queue中。

我们可以用数组queue[140]和结构体queue来区分它们。

当有PCB从里面链入或者链出时,nr_active和bitmap都会相应更新

我们可以知道,一个结构体queue就能将进程按优先级处理完,但进程的处理是动态的过程,我们要知道他是怎么流转起来的。这就需要知道runqueue的结构了。

(2)runqueue

runqueue是以结构体queue为基本结构,为满足动态调度而建立起来的。其中active活跃指针指向的array里面的PCB* queue[140]就是CPU正在调度的PCB队列,换句话说,调度器只会从active指向的PCB队列中调度进程。这样实现为什么呢?那另一个array干什么呢?我们需要设想,如果在CPU执行的过程中由新的进程加入进来怎么办?同时,CPU要如何在既保证优先级又保证较为公平的调度呢?

(3)调度算法

①新增:当有新的进程加入runqueue时,它并不会直接加入active指向的队列,而是会链入expired指向的结构体queue里面的PCB* queue[140],链入规则和前面一样,都遵循哈希算法。

②现有的进程:当active指向的队列里的一个进程被执行完一次之后,它并不会被链入到当前active对应的PCB* queue[140],而是会和那些新进程一样,链入expired指向的PCB* queue [140]中。

③完成的进程:当有进程在active被执行一次并完成后,就会进入Z+X状态,就不会被链入expired里面的PCB* queue [140],等着被父进程读取回收就行了

我们发现,expired对应的PCB* queue [140]对应的PCB*越来越多(nr_active也增大),而active对应的PCB* queue [140]却越来越少(nr_active减小)。当nr_active == 0时,active和expired的指针交换,这个时候我们就发现expired(原来的active)空了,active(原来的expired)满了。接下来就继续按上述规则执行(active取,放回expired,新增放入expired),如此往复,一个动态的调度过程就形成了。

从上述过程我们就能发现整个调度过程既保证了优先级,也保证了公平性,同时新增入的进程也不会和正在执行的进程发生冲突。调用规则保证了每一次循环active里面的每一个PCB都会被执行(nr_active记录PCB*数量,每调用一次就减1,不会遗漏),而按照顺序调用又保证了优先级,即优先级高的先执行,低的后执行。

(4)bitmap存在的意义

runqueue中active、expired、array[2]存在的意义很明确,没有它们就构不成整个调度的流转,上述的过程就是它们存在的意义。对于queue来说,nr_active用于记录PCB*的数量,即active、expired分别指向的结构体里进程的数量,只有当active里面的进程调度完了(nr_active == 0)才会swap两个指针,它明确了每次swap的时机,也保证了调度进程的公平性。

但还有个细节,那就是遍历PCB* queue [140]效率不高,明明数组可以随机访问,但又要保证所有PCB都被访问,所以就有bitmap的出现。通过160位bit我们可以得到140个位置存放PCB的情况,比如假定bitmap[0]是5,根据101B,我们得到PCB* queue[140]的第0位和第2位有进程,其余30位都没有进程,可以直接跳过。每个int我们就可以扫掉32个位置,效率很高。具体操作涉及到位操作,之前也有讲过一些位操作得到1或0的办法,很多,这里我们明白是怎么一回事即可。

总结:这是一个进程饥饿问题(公平与优先级的矛盾),采用双queue来解决问题,使得active永远处于存量竞争状态,随着时间竞争越来越小,再交换指针重复操作,实现公平与优先级共存。整个调度算法框架的时间复杂度控制在O(1),效率很高。

2.Linux内核链表

我们常见的链表无外乎分为带头和不带头、单向还是双向、循环还是不循环。这种链表有个共同特点,就是数据和链绑定在了一起。但在Linux内核中,一个PCB,它有可能既是在queue队列,又有可能在waitqueue,那么我们应该怎么做呢?这就是Linux的内核链表,它将链和数据分离,用位操作来访问,极大增强了数据链接和访问的效率。

但这种链表访问数据很麻烦,因为我们只能得到链表连接点的地址,而其它地方的地址并不好拿,我们要想办法拿到struct的起始地址。思路是&(struct  A*)0->(要查找的成员变量链接点)可以得到偏移量offset(宏),再使用(链接点) - offset得到struct A的起始地址,之后就能正常访问了。难点在C语言,学习过偏移量和宏应该能很快理解。

PCB之间就是用这种链表联系起来的,在不同状态切换的效率上很有优势

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

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

相关文章

谷歌给到的185个使用生成式AI的案例

很多公司从利用AI回答问题,进而使用AI进行预测,向使用生成式AI Agent转变。AI Agent的独特之处在于它们可以采取行动以实现特定目标,比如引导购物者找到合适的鞋子,帮助员工寻找合适的健康福利,或在护理人员交接班期间…

python之输入输出

1、输入 Python在控制台输入内容,需要使用input函数。input函数会在控制台等待用户输入,直到用户按下了回车键才算完成输入。 注意:input函数接收的内容为字符串。 str1 input("请输入内容\n") print(str1) print(type(str1))1…

Python酷库之旅-第三方库Pandas(132)

目录 一、用法精讲 591、pandas.DataFrame.plot方法 591-1、语法 591-2、参数 591-3、功能 591-4、返回值 591-5、说明 591-6、用法 591-6-1、数据准备 591-6-2、代码示例 591-6-3、结果输出 592、pandas.DataFrame.plot.area方法 592-1、语法 592-2、参数 592-…

9.28学习笔记

1.ping 网址 2.ssh nscc/l20 3.crtl,打开vscode的setting 4.win 10修改ssh配置文件及其密钥权限为600 - 晴云孤魂 - 博客园 整体来看: 使用transformer作为其主干网络,代替了原先的UNet 在latent space进行训练,通过transformer处理潜…

查缺补漏----该不该考虑不可屏蔽中断

可以看看这个视频: 讨论中断时,该不该考虑不可屏蔽中断?_哔哩哔哩_bilibili 首先要知道一个概念:可屏蔽中断和不可屏蔽中断 可屏蔽中断: 可屏蔽中断是可通过中断屏蔽字来启用或禁用的中断。对于多级中断而言&#…

①EtherCAT转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherCAT 转 ModbusTCP GW系列型号 MS-GW15 简介 MS-GW15 是 EtherCAT 和 Modbus TCP 协议转换网关,为用户提供一种 …

map_set的使用

map_set的使用 关联式容器树形结构的关联式容器setset的介绍set的使用 multisetmultiset的介绍multiset的使用 mapmap的介绍map的使用键值对 multimapmultimap的介绍 🌏个人博客主页:个人主页 关联式容器 在初阶阶段,我们已经接触过STL中的部…

黑科技外绘神器:一键扩展图像边界

黑科技外绘神器:一键扩展图像边界 Diffusers Image Outpaint✨是一个开源工具,能智能扩展图像边界,创造完美视觉效果🏞️。用户可自定义风格,生成高清图像🤩,应用场景广泛,释放你的…

大模型~合集6

我自己的原文哦~ https://blog.51cto.com/whaosoft/11566566 # 深度模型融合(LLM/基础模型/联邦学习/微调等) 23年9月国防科大、京东和北理工的论文“Deep Model Fusion: A Survey”。 深度模型融合/合并是一种新兴技术,它将多个深度学习模…

爬虫——爬取小音乐网站

爬虫有几部分功能??? 1.发请求,获得网页源码 #1.和2是在一步的 发请求成功了之后就能直接获得网页源码 2.解析我们想要的数据 3.按照需求保存 注意:开始爬虫前,需要给其封装 headers {User-…

本地化测试对游戏漏洞修复的影响

本地化测试在游戏开发的质量保证过程中起着至关重要的作用,尤其是在修复bug方面。当游戏为全球市场做准备时,它们通常会被翻译和改编成各种语言和文化背景。这种本地化带来了新的挑战,例如潜在的语言错误、文化误解,甚至是不同地区…

C++ 双端队列(deque)的深入理解

前言: 双端队列deque看起来是一个相当牛的容器,表面看起来将list和vector进行结合起来,形成了一个看起来很完美的容器,但是事实不是这样,要是deque如此完美,数据结构也就没list和vector的事情了&#xff0c…

多系统萎缩患者必看!这些维生素助你对抗病魔

亲爱的朋友们,今天我们来聊聊一个相对陌生但重要的健康话题——多系统萎缩(MSA)。这是一种罕见的神经系统疾病,影响着患者的自主神经系统、运动系统和平衡功能。面对这样的挑战,科学合理的饮食和营养补充显得尤为重要。…

暴力数据结构——AVL树

1.认识AVL树 AVL树最先发明的⾃平衡⼆叉查找树,AVL可以是⼀颗空树,或者具备下列性质的⼆叉搜索树: • 它的左右⼦树都是AV树,且左右⼦树的⾼度差的绝对值不超过1 • AVL树是⼀颗⾼度平衡搜索⼆叉树, 通过控制⾼度差去控制平衡 AVL树整体结点…

路由交换实验指南

案例 01:部署使用 eNSP 平台实验需求: 安装华为 eNSP 网络模拟平台打开 eNSP 平台,新建拓扑并绘制网络能够成功启动交换机、计算机设备 实验步骤: 安装华为 eNSP 网络模拟平台启动安装程序 配置安装内容 防护墙允许 eNSP 程序的…

IDTL:茶叶病害识别数据集(猫脸码客 第205期)

Identifying Disease in Tea Leaves茶叶病害识别数据集 一、引言 在农业领域,茶叶作为一种重要的经济作物,其生产过程中的病害防治是确保茶叶质量和产量的关键环节。然而,传统的病害识别方法主要依赖于人工观察和经验判断,这不仅…

从零开始实现RPC框架---------项目介绍及环境准备

一,介绍 RPC(Remote Procedure Call)远程过程调⽤,是⼀种通过⽹络从远程计算机上请求服务,⽽不需要 了解底层⽹络通信细节。RPC可以使⽤多种⽹络协议进⾏通信, 如HTTP、TCP、UDP等, 并且在 TCP/…

匿名方法与Lambda表达式+泛型委托

匿名方法 和委托搭配使用,方便我们快速对委托进行传参,不需要我们定义一个新的函数,直接用delegate关键字代替方法名,后面跟上参数列表与方法体。 格式:delegate(参数列表){方法体} lambda表达式 是匿名方法的升级…

Brave编译指南2024 MacOS篇-环境配置(四)

引言 在上一篇文章中,我们成功获取了Brave浏览器的源代码。现在,我们将进入编译过程的关键阶段:环境配置。正确的环境配置对于成功编译Brave浏览器至关重要,它能确保所有必要的工具和依赖项都已就位,并且版本兼容。 …

JAVAIDEA初始工程的创建

四结构 建工程综述* 初始*: 1、先建个空项目, 2、打开文件中的项目结构新建module模块(模块下有src) 修改模块名: 也是Refactor,Rename,但是要选第三个同时改模块和文件夹名字 导入模块&am…