Linux---进程(五)进程调度

一、

Linux内核中用双向链表管理进程控制块。

在OS的角度,Linux内核的struct list_head是一种侵入式的双向链表,把链表节点直接嵌入到task_struct 等数据结构中,有点非常突出:

(1)通用性极强:链表操作不依赖具体的数据类型,同一套API可以管理任意的结构体,避免了为每种数据结构重复写链表代码。

(2)多队列共存:一个task_struct可以嵌入多个list_head,比如tasks(全局进程链表)、run(运行队列)、children(子进程链表),让同一个进程同时属于多个队列,方便不同场景的管理。

(3)高效灵活:双向链表的插入删除操作是O(1)时间复杂度,内核平频繁调度进程时性能极高;同时通过container_of宏可以从链表节点快速反查到所属的task_struct

(4)内存开销小:链表节点只存指针,不存数据,避免了额外的内存开销,非常适合资源紧张的内核环境。

每一个CPU都有一个调度队列。

不同的结构体对象,也可以用链表链接;只要在不同的结构体里都嵌入struct list_head,就可以用同一套API把他们串起来。

二、调度队列

queue140

如上图:这个是调度队列

位图(bitmap)

1、位图(bitmap)到底是什么?

在 Linux O(1) 调度器的语境下,位图(bitmap) 就是一个由 0 和 1 组成的二进制数组,它的核心作用是:快速标记"哪些优先级队列里还有待运行的进程"。

它是 prio_array_t 结构体里的 bitmap5 成员。

它的每一位(bit),都对应着 queue140 数组里的一个优先级队列。

2、位图和优先级队列的关系

  1. 对应关系:

位图的第 i 位 ↔ 优先级为 i 的队列 queuei

  • 位图第 i 位为 1 → queuei 非空(有进程等待调度)。

位图第 i 位为 0 → queuei 为空(没有进程等待调度)。

  1. 结构关系:

你图中的 prio_array_t 结构体包含两个数组: array0 (活跃进程)和 array1 (过期进程)。

每个数组里都有自己独立的 bitmap5 和 queue140 ,分别管理各自的进程队列状态。

3、如何判断一个队列是否为空?

判断一个队列是否为空,有两种方式:

  1. 直接检查队列:

去看 queuei 这个链表的头指针,如果它指向自己(即链表为空),则队列为空。

这种方法是 O(1),但如果要找最高优先级,就需要遍历所有队列,变成 O(n)。

  1. 通过位图间接判断(O(1) 调度器的核心):

当一个进程加入 queuei 时,内核会把位图的第 i 位 置为 1。 当 queuei 里最后一个进程被取走时,内核会把位图的第 i 位 清为 0。

所以,调度器在选择下一个进程时,不需要逐个检查队列,只需要扫描位图,找到第一个值为 1 的位,这个位的索引 i 就是当前最高优先级,对应的 queuei 就是非空的。

4、为什么要用位图?

速度快:把"遍历 140 个队列"的 O(n) 操作,变成了"扫描位图找第一个 1"的 O(1) 操作。

空间省:用 140 个比特(约 18 字节)就存下了所有队列的状态信息,非常紧凑。

设计巧:这正是 O(1) 调度器名字的由来,它能在常数时间内完成调度决策。

nr_active

记录总进程个数

进程调度规则

Linux O(1)调度算法

1、刚开始,所有进程都是在active里面的,expired是空的,调度器只从active里面选进程。

2、每个进程都会有时间片,时间一到,就把这个进程从active移到expired,重新给它分配时间片。

3、等到active里面一个进程都没有了,系统不复制,不搬运,只做一件事,把active和expired交换身份。此时就是原来的active变为新的expired,原来的expired变为active。(两个指针交换)

4、现在新的active里面全是重新充好时间片的进程,调度器又开始从这里面选择进程运行。

按照上面的规则一直循环往复

相关推荐
2301_777998345 小时前
Linux信号机制
linux
一叶龙洲7 小时前
win11与Ubuntu之间同步配置、插件
linux·运维·ubuntu
CHANG_THE_WORLD8 小时前
12.总结:深入理解 Linux I/O 多路复用:select、poll、epoll 全解析
linux·运维·服务器
风曦Kisaki8 小时前
# Linux笔记:操作系统优化与资源管理
linux·运维·服务器·笔记
Mr.HeBoYan9 小时前
一次持续三天才出现的丢包故障——深入解析 DPDK Memory Ordering、rte_ring 与 CPU Memory Barrier (下)
linux·网络·算法·架构·dpdk
zhangrelay10 小时前
笔记本轻量高品质延寿工具完整分系统清单
运维·笔记·学习
初願致夕霞11 小时前
C++懒汉单例设计详解
服务器·开发语言·c++
Discipline~Hai11 小时前
ARM01-ARM体系架构
linux·c语言·arm开发·架构
RisunJan12 小时前
Linux命令-screen(终端复用器)
linux·运维
啊哦11112 小时前
安装VMware Workstation
linux·运维·服务器