Linux2.6内核进程调度队列

news/2024/5/5 1:44:15

目录

运行队列runqueue

活跃队列&过期队列

queue[140]&优先级&队列数组下标

bitmap[5]&O(1)调度算法

nr_active

active指针和expired指针

O(1)调度算法之调度过程


本篇是Linux进程概念篇的最后一篇,Linux2.6内核是一个具体的/可行的/实际的存在的一个调度方案。下篇我们将进入进程控制篇。

运行队列runqueue

下图是Linux2.6内核中进程队列的数据结构,之间关系已经给大家画出来,方便大家理解。

  • 一个CPU拥有一个runqueue (struct runqueue)
  • runqueue是CPU的PCB(task_strutc)
  • 如果有多个CPU就要考虑进程个数的负载均衡问题
  • 我们现在谈论的OS都是分时操作系统,调度时强调的是公平!
  • 关于实时操作系统,暂且不谈,调度时强调的时实时性!智能自动驾驶骑车等。

 

活跃队列&过期队列

  • CPU调度时,需要把进程拿走的同时,把正在执行的进程剥离下来(被放入运行队列)
  • 运行队列中存在两套相同的结构体类型。
  • 拿走的队列:活跃队列。放入队列:过期队列。
  • 活跃队列表示当前CPU正在执行的运行队列,而正在执行的运行队列(也就是活跃队列)是不可以增加新的进程的 。
  • 与此同时,操作系统设置了一个 和活跃队列相同属性的过期队列当活跃队列正在执行时如果有进程需要添加进运行队列,那么就会添加至过期队列当中也就是说 活跃队列的进程一直在减少,而过期队列中的进程一直在增多!
  • 活跃队列是只出不进
  • 过期队列是只进不出
  • 两个队列是被存放在结构体数组中的,结构体数组存放在运行队列中
  • 且运行队列中存在active指针和expired指针分别指向活跃队列和过期队列。

活跃队列

  • 时间片还没有结束的所有进程都按照优先级放在该队列
  • nr_active: 总共有多少个运行状态的进程
  • queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级!
  • 从该结构中,选择一个最合适的进程,过程是怎么的呢?
  1. 从0下表开始遍历queue[140]
  2. 找到第一个非空队列,该队列必定为优先级最高的队列
  3. 拿到选中队列的第一个进程,开始运行,调度完成!
  4. 遍历queue[140]时间复杂度是常数!但还是太低效了!
  • bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个比特位表示队列是否为空,这样,便可以大大提高查找效率!

过期队列

  • 过期队列和活动队列结构一模一样
  • 过期队列上放置的进程,都是时间片耗尽的进程
  • 当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算

queue[140]&优先级&队列数组下标

  • task_struct *queue[140]
  • 维护的是一个140个队列的进程PCB的数组(指针数组)
  • 数组有140个元素,每个元素指向一个队列的第一个进程PCB,存放的PCB地址。
  • 140个下标可以包含140个队列。但是❗只用100~139的下标&队列。(40个)

之前我们笼统的理解为进程的调度是进程的PCB在runqueue里面排队,其实是在上面的queue里面排队。

  • 怎么体现优先级呢❓前面提到进程的优先级只有40个。
  • 若进程的优先级相同又该怎么办呢❓
  • 进程的优先级也是[60,99](40个)
  • 普通优先级:100~139(我们都是普通的优先级,想想nice值的取值范围,可与之对应!)
  • 实时优先级:0~99(不关心)

优先级和队列数组下标转化:

  • 优先级+40=下标值
  • 下标值-40=优先级的值
  • 存在一一对应的关系

例:优先级为60的进程直接把进程的PCB链接到下标值:60+40=100的地方。

所以表面看起来,LinuxOS维护了一个运行队列,但实际上OS维护了40个运行队列。

CPU调度一个进程找到运行队列数组,找到活跃队列,以优先级顺序找到队列,取队列中第一个进程的PCB来调度。

bitmap[5]&O(1)调度算法

如果前面大面积没有进程PCB存放,只有在后面才有进程PCB存放。那么CPU在调度进程时,需要遍历数组,才能找到存放进程PCB的位置。效率低且麻烦。

  • 由我们bitmap数组去解决这个问题!其实就是位图法,在我们C++也会学习到!
  • long bitmap[5]
  • long是4个字节,8*4=32个bite位,有32*5=160个bite位
  • 把数组中的每一个位置的队列看成bitmap中的一个bit位(0/1序列)
  • 只用140个位置
  • 设定:bit位为0的表示队列数组中的这个位置的队列无进程PCB
  • bit位为1的表示队列数组中的这个位置的队列有进程PCB
  • 所以,CPU不需要遍历140的队列数组,只需要遍历bitmap的5个位置,遍历一次就查找了32个bite位,大大提高了效率!
  • 时间复杂度位O(1),所以O(1)调度算法!

nr_active

  • 在Linux内核中,nr_active通常与进程调度、任务管理或资源计数有关。它通常用于表示当前活跃的任务或资源的数量。
  • 在Linux内核2.6版本中,nr_active可能出现在多个上下文中,例如任务队列、进程描述符或资源管理器中。这个变量通常用于跟踪系统当前正在处理或可用的任务数量,以便内核可以进行适当的调度和资源分配
  • 请注意,nr_active的具体含义和用途可能取决于它在内核代码中的具体实现和上下文。因此,要准确理解nr_active在Linux内核2.6中的含义,您需要查阅该版本的源代码,并查找nr_active的使用位置。

active指针和expired指针

运行队列中存在active指针和expired指针分别指向活跃队列和过期队列。CPU调度时只找active指向的队列。

在Linux内核中,特别是在进程调度和任务管理的上下文中,active指针和expired指针通常与运行队列(runqueue)相关。运行队列是内核用于管理和调度进程的数据结构。

  1. active指针
    active指针通常指向当前活跃的任务或进程。活跃任务是指那些已经准备好运行但尚未被调度器选中的进程。这些进程通常位于CPU的运行队列中,等待调度器的调度。active指针帮助内核快速定位并调度这些活跃进程。
  2. expired指针
    expired指针则用于管理那些已经超过其运行时间限制或因为其他原因而被标记为“过期”的进程。这些进程不再处于活跃状态,但仍然需要被适当地处理,例如可能需要被唤醒或重新调度。expired指针帮助内核跟踪这些过期的进程,以便在需要时进行处理。
  • active指针永远指向活动队列
  • expired指针永远指向过期队列
  • 可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。
  • 没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了一批新的活动进程!

这两个指针是内核调度器用于有效管理进程运行队列的重要工具。通过它们,内核能够高效地调度和执行进程,确保系统的正常运行和性能优化。


  1. CPU正在执行访问的队列是active指向的A活跃队列(只出不进)
  2. 另外一个被expired指向的结构相同的过期队列B(只进不出)
  3. 新创建的进程的PCB只链接到过期队列B
  4. CPU调度的活跃队列A中的进程PCB被CPU调度时间片到了之后,也链接到过期队列B
  5. 最后A队列中的进程被CPU全部调度完/处理完,B队列也满满的
  6. 接着将两个active指针和expired指针交换swap(active,expired),交换的是指针内容
  7. 重复上诉过程

 

O(1)调度算法之调度过程

  • CPU正在执行访问的队列是active指向的A活跃队列(只出不进)
  • 另外一个被expired指向的结构相同的过期队列B(只进不出)
  • 新创建的进程的PCB只链接到过期队列B
  • CPU调度的活跃队列A中的进程PCB被CPU调度时间片到了之后,也链接到过期队列B
  • 最后A队列中的进程被CPU全部调度完/处理完,B队列也满满的
  • 接着将两个active指针和expired指针交换swap(active,expired),交换的是指针内容
  • 重复上诉过程
  • 在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增加,我们称之为进程调度O(1)算法!
  • Linux的进程优先级 NI 和 PR - 简书 (jianshu.com)

🙂感谢大家的阅读,若有错误和不足,欢迎指正。


http://www.mrgr.cn/p/07016153

相关文章

深入理解Linux文件系统和日志分析

目录 一.inode与block 1.inode与block概述 1.1.文件数据包括元信息与实际数据 1.2.文件存储在硬盘上,硬盘最小存储单位是“扇区”,每个扇区存储512字节 1.3.block(块) 1.4.inode(索引节点) 2.inode内…

军工单位安全内网文件导出,怎样做到严密的安全管控?

军工单位是指承担国家下达的军事装备、产品研制、生产计划任务的企、事业单位,主要包括电子工业部、航空工业总公司、航天工业总公司、兵器工业总公司、核工业总公司、船舶工业总公司、中国工程物理研究院及各省国防工业办公室等。 军工单位的特点主要体现在以下几个方面: 承…

Vue3中使用无缝滚动插件vue3-seamless-scroll

官网:https://www.npmjs.com/package/vue-seamless-scroll 1、实现效果文字描述: 表格中的列数据进行横向无缝滚动,某一列进行筛选的时候,重新请求后端的数据,进行刷新 2、安装:npm i vue3-seamless-scrol…

Keil和VSCode协同开发STM32程序

系列文章 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 配置环境 2. 测试打开工程 3. 测试编译工程 随着项目的复杂度上升,开发者不仅需要强大的硬件支持,还需要一个高效和灵活的开发环境。 vscode是一款集成大量可以便携开发插件的代码…

爬虫js逆向(python调用js学习)

首先介绍pyexecjs的使用 PyExecJs 是一个python 库,用于在 Python 环境中执行javaScript代码。它实际上是对 Execs 库的 Python 封装,Execls 本身是一个通用的 JavaScript 运行环境的抽象层。使用PyExecJs,你可以在Python 中执行JavaScript代码,而无需启动一个完整的JavaSc…

维基百科、百度百科和搜狗百科词条的创建流程

随着网络的发展,百度百科、搜狗百科、维基百科等百科网站已经成为大众获取知识的重要途径。因为百科具有得天独厚的平台优势,百科上的信息可信度高,权威性强。所以百科平台也成为商家的必争之地。这里小马识途聊聊如何创建百度百科、搜狗百科…

贪吃蛇(C语言版)

在我们学习完C语言 和单链表知识点后 我们开始写个贪吃蛇的代码 目标:使用C语言在Windows环境的控制台模拟实现经典小游戏贪吃蛇 贪吃蛇代码实现的基本功能: 地图的绘制 蛇、食物的创建 蛇的状态(正常 撞墙 撞到自己 正常退出&#xf…

智能组网怎么样?

智能组网技术的出现,使得网络连接更加便捷和智能化。无论我们身处何地,只要有网络覆盖,就能轻松进行远程连接和访问。智能组网到底如何实现的呢?本文将就智能组网的优势进行探讨,以便更好地了解其特点和应用场景。 【天…

idle的下载和环境配置(python)

1.进入官网:https://www.python.org/ 2.downloads->windows选择对应版本(这里我选择3.10.0是因为听说10比较稳定) 3. 找到刚下载的Python程序安装包,双击打开,运行安装程序。 直接点击下一步,直至安装成功,点击完成就可以了。如果想切换安装目录,可以在那一步换一下安…

自己手动在Linux上实现一个简易的端口扫描器

背景 常常听到网络攻击有一个东西叫做端口扫描器,可以扫描指定服务器开放的端口,然后尝试连接,并寻找漏洞,最终攻破服务器。而那些使用的端口扫描器都是一个个现成的程序,看上去很厉害的样子。而实际上这些东西对于懂…

[dp 小计] SOSdp

复健 SOSdp(sum over subsets dynamic programming)。 引入 令 \(F(x)=\sum\limits_{u\subseteq x} A(u)\) 其中 \(A\) 为给定数组,求出 \(\forall x, F(x)\) 。 思路一 暴力枚举子集,时间复杂度 \(O(4^n)\)。 思路二 优化子集枚举,时间复杂度 \(O(3^n)\)。 思路三 考虑 SOS…

HTTP慢连接攻击的原理和防范措施

随着互联网的快速发展,网络安全问题日益凸显,网络攻击事件频繁发生。其中,HTTP慢速攻击作为一种隐蔽且高效的攻击方式,近年来逐渐出现的越来越多。 为了防范这些网络攻击,我们需要先了解这些攻击情况,这样…

Redis篇:缓存击穿及解决方案

1.何为缓存击穿 缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了(有可能是正好过期了),无数的请求访问会在瞬间给数据库带来巨大的冲击。 常见的解决方案有两种: 互斥锁 逻…

【深度学习】yolo-World,数据标注,zeroshot,目标检测

仓库:https://github.com/AILab-CVC/YOLO-World 下载权重: 仓库下载和环境设置 下载仓库:使用以下命令从 GitHub 上克隆仓库: git clone --recursive https://github.com/AILab-CVC/YOLO-World.git创建并激活环境&#xff1a…

Xinlinx FPGA内的存储器BRAM全解

目录 一、总体概述1.7系列FPGA的BRAM特点2.资源情况 二、BRAM分类1.单端口RAM2.简单双端口RAM3.真双端口RAM 三、BRAM的读写1、Primitives Output Registers读操作注意事项2.三种写数据模式(1)Write_First(2)Read_First&#xff0…

贪吃蛇的简单实现(c语言)

前言:学完了C语言的基础语法,和一点数据结构的知识,拿贪吃蛇来练练手,并熟悉以前的知识。写完之后,有一种成就感,为以后的学习饱满激情。 注意这里的讲解是由部分到整体的思路。 目录 控制台不能是终端&am…

UE4网络图片加载库(带内存缓存和磁盘缓存)

UE4网络图片加载库,带内存缓存和磁盘缓存,支持自定义缓存大小,支持蓝图和C++代码调用 1、调用示例 2、对外暴露函数 3、源代码-网络模块 KeImageNet.h // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreM…

BERT-CRF 微调中文 NER 模型

文章目录 数据集模型定义数据集预处理BIO 标签转换自定义Dataset拆分训练、测试集 训练验证、测试指标计算推理其它相关参数CRF 模块 数据集 CLUE-NER数据集:https://github.com/CLUEbenchmark/CLUENER2020/blob/master/pytorch_version/README.md 模型定义 imp…

vulfocus靶场couchdb 权限绕过 (CVE-2017-12635)

Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库"。它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL数据库。应用广泛,如BBC用在其动态内容展示平台&…

WDS+MDT网络启动自动部署windows(七)添加驱动

简介: 以前的ghost,是封装万能驱动。 现在安装原版ISO,是手动安装驱动。 那么WDS+MDT,怎么装驱动更方便呢? 本来是轻接触,lite touch,通过设置rules,bootstrap,可以达到只选择一下任务序列即可。 那么也要自动安装驱动。 WDS也可以注入驱动,但是是在使用原版安装镜像…