[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)算法。
完~
未经作者同意禁止转载
相关文章:
[Linux] Linux 的进程如何调度——Linux的 O(1)进程调度算法
标题:[Linux] Linux 的进程如何调度——优先级与进程调度 个人主页水墨不写bug 目录 一、前言 二、将要出现的概念 1.进程调度队列 2.位图 3.进程的优先级 三、Linux进程的调度过程 1.活动队列(*active指向的队列) 2.过期队列&#…...
Python使用Selenium动态爬取CSDN社区帖子的URL链接
前几天读了一篇CSDN社区的帖子,发现文章内容写得极好,值得借鉴学习。于是我想将那个社区的帖子都爬下来,但是那个社区发布的贴子挺多的,一直往下拉才到2022年5月的发布。于是我就只将5月份之前的爬下来就行,但是帖子是…...
【ShuQiHere】双系统指南:如何在 Linux 系统情况下安装 Windows 11,处理引导与网络问题 ️
【ShuQiHere】 🖥️💡 在安装 Windows 11 和 Linux 双系统时,常常会遇到各种棘手的问题,特别是在网络连接、BIOS 设置和引导修复方面。今天我将详细带你解决这些问题,让你顺利完成 Windows 11 安装,并恢复…...
jQuery EasyUI 扩展
jQuery EasyUI 扩展 引言 jQuery EasyUI 是一个流行的 HTML5 框架,用于构建交互式网页界面。它提供了一系列的 UI 组件,如布局、窗口、数据网格等,使得网页开发变得更加简单快捷。然而,尽管 EasyUI 功能丰富,但在某些特定场景下,开发者可能需要更多的定制化功能或组件。…...
408算法题leetcode--第24天
#378. 有序矩阵中第 K 小的元素 378. 有序矩阵中第 K 小的元素思路:值二分,如注释时间:O(log(r-l) * n);空间:O(1) class Solution { public:int check(vector<vector<int>>& matrix, int target){/…...
【CKA】二、节点管理-设置节点不可用
2、节点管理-设置节点不可用 1. 考题内容: 2. 答题思路: 先设置节点不可用,然后驱逐节点上的pod 这道题就两条命令,直接背熟就行。 也可以查看帮助 kubectl cordon -h kubectl drain -h 参数详情: –delete-empty…...
STM32中断编程指南:NVIC和中断优先级
在STM32微控制器编程中,中断是实现多任务处理和实时响应的关键技术。NVIC(Nested Vectored Interrupt Controller)是STM32中的中断控制器,负责管理中断请求、优先级和中断向量。本文将详细介绍STM32的NVIC配置和中断优先级设置&am…...
ThreadLocal底层原理及数据结构详解
ThreadLocal允许为每个线程创建独立的变量副本,使得同一个ThreadLocal对象在不同的线程中拥有不同的值。它的主要作用是在并发环境下提供线程隔离,避免多个线程共享同一个变量,从而减少线程间的相互干扰。 ThreadLocal的核心在于为每个线程维…...
Android Framework AMS(02)AMS启动及相关初始化5-8
该系列文章总纲链接:专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明: 说明:本章节主要涉及systemserver启动AMS及初始化AMS相关操作。同时由于该部分内容过多,因此拆成2个章节,本章节是第二章节&…...
速盾:游戏被攻击怎么办?
随着游戏行业的发展,游戏被攻击的情况也越来越多见。游戏被攻击可能导致游戏服务器崩溃、用户数据泄露、游戏体验受影响等问题。作为游戏开发者或运营商,面对游戏被攻击的情况,应该采取一系列的措施来应对。 首先,要及时发现游戏…...
BUU刷题-Pwn-shanghai2018_baby_arm(ARM_ROP_csu_init,ARM架构入门)
解题思路: 泄露或修改内存数据: 堆地址:无需栈地址:无需libc地址:无需BSS段地址:无需 劫持程序执行流程:ARM_ROP && mprotect函数(运行内存权限修改) && [[ARM_ROP_csu_init]…...
flutter_鸿蒙next(win)环境搭建
第一步 拉取鸿蒙版本flutterSDK仓库 仓库地址:OpenHarmony-SIG/flutter_flutter 第二步 找到拉取的仓库中的README.md 并根据说明配置环境 第三步 配置好环境变量之后 用管理员开启cmd 输入:flutter dcotor 并查看此时flutter所支持的系统 包括&…...
腾讯一面-LRU缓存
为了设计一个满足LRU(最近最少使用)缓存约束的数据结构,我们可以使用哈希表(HashMap)来存储键值对,以便在O(1)时间复杂度内访问任意键。同时,我们还需要一个双向链表(Doubly Linked …...
k8s实战-1
k8s实战-1 一、资源创建方式1.命令行2.yaml 二、命名空间三、Pod总结 一、资源创建方式 1.命令行 就是直接通过命令的方式创建,比如我要创建namespace, kubectl create namespace hello删除: kubectl delete -f hello2.yaml 简单来说&am…...
Python进程池:提升你的并发性能
引言 在现代编程中,多核处理器的普及使得并发编程变得尤为重要。Python,作为一种广泛使用的编程语言,提供了多种并发和并行编程的工具。其中,multiprocessing库中的进程池(Pool)是一个强大的工具ÿ…...
内存占用估算方法
优质博文:IT-BLOG-CN 通过掌握每种数据类型的大小,就可以更准确地预测对象和数据的内存消耗。 一、基础数据类型 Java基础数据类型结构,在64位系统开启指针压缩情况下的内存占用字节数: booleanbytecharshortintlongfloatdoub…...
拓扑排序简介
拓扑排序(Topological Sort)是一种重要的图算法,用于对有向无环图(DAG, Directed Acyclic Graph)中的节点进行排序。拓扑排序的结果是一种线性序列,使得对于图中的任意一条有向边(u, v),顶点u都在顶点v之前。这种排序常用于任务调度、编译器依赖关系分析等领域。 拓…...
使用iTextPDF库时,设置文字为中文格式
在使用iTextPDF库时,设置文字为中文格式主要涉及选择合适的中文字体,并确保该字体能够正确渲染中文字符。由于iTextPDF的内置字体通常不支持中文,因此你需要加载一个支持中文的字体文件(如TrueType字体,.ttf文件&#…...
Windows环境下使用Docker配置MySQL数据库
用Docker配置数据库,无论是做开发,还是做生产部署,都非常的方便 它不需要单独安装数据库,也不用担心出现各种环境的配置问题。 本文将分享用Docker配置数据库的步骤,这里用MySQL举例。 其他的数据库如MSSQL…...
快速上手C语言【上】(非常详细!!!)
目录 1. 基本数据类型 2. 变量 2.1 定义格式 和 命名规范 2.2 格式化输入和输出(scanf 和 printf) 编辑 2.3 作用域和生命周期 3. 常量 4. 字符串转义字符注释 5. 操作符 5.1 双目操作符 5.1.1 算数操作符 5.1.2 移位操作符 5.1.3 位操作符…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...


