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里面全是重新充好时间片的进程,调度器又开始从这里面选择进程运行。

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

相关推荐
ai_xiaogui4 分钟前
PanelAI应用市场跑通!一键部署容器 + 服务器迁移宝塔面板安装全记录
服务器·宝塔面板安装教程2026·服务器重装系统迁移·panelai应用市场·轻量服务器优化swap·ai项目一键部署·panelai部署容器
Irissgwe10 分钟前
9、数据链路层
linux·网络·mac·ip·数据链路层·arp协议·以太网帧格式
lwprain31 分钟前
Umi-ocr2.1.5的linux部署,仅做记录
linux·服务器·umi-ocr
鹏大师运维37 分钟前
统信UOS安装Subtitle Edit并使用Edge-TTS生成AI语音教程
linux·前端·人工智能·edge·麒麟·统信uos·ai语音
cjp56039 分钟前
002.WEB API 服务器 RESTful规范
服务器
syagain_zsx39 分钟前
Linux进程全面解析:从基础到高级管理(1/3)
linux
实心儿儿1 小时前
Linux —— 线程池(1)
linux
卧室小白1 小时前
K8S-Pod基本配置
linux·运维·服务器
yyuuuzz1 小时前
谷歌云基础服务的入门认知
linux·运维·服务器·数据库·人工智能·github
煜声远播1 小时前
相册卡顿的系统级排查复盘:fsync 不要在锁里调用
linux