Linux:进程切换与调度
一、进程优先级1.1 什么是进程优先级进程优先级是指进程获得CPU资源先后顺序的数值数值越小优先级越高。优先度越高的进程有优先执行的权利而配置进程优先度对执行多任务环境的Linux系统有明显的帮助可以改善系统的性能。1.2 PRI值和NI值当我们用ps -l查看系统进程时我们很容易发现其中几个重要的属性信息其中有关于我们进程优先级的属性是PRI值和NI值PRI值PRI还是比较好理解的就是该进程的优先级通俗点来说就是程序被CPU执行的先后顺序该值越小进程的优先级越高。NI值NI值就是我们所说的nice值表示进程可被执行的优先级的修正数值。PRI值越小的越优先被执行而有了NI值后我们PRI新 PRI旧 NI。当NI值为正时PRI值变大优先级变低NI值为负时PRI值变小优先级变高。那我们将NI值无限调小或调大岂不是能将某进程的优先级变得极高或极低答案当然是不可能的系统规定我们的NI值的设定范围为[-2019]当我们设定的NI值小于-20或大于19时系统自动将NI值变得-20或19不会超出所规定的范围。另外一般系统是不允许更改PRI值默认80的只能更改NI值来间接更改PRI值优先级的更改也是不支持高频修改的一段时间是不能多次更改NI值。二、进程切换2.1 并行与并发进程具有独立性和竞争性那么如何将有限的CPU资源分配给多个独立并竞争的进程这里系统有两种调度方式并行与并发。并行多个进程在多个CPU下分别同时的进行运行。并发多个进程在一个CPU中采用进程轮换的方式在一段时间内让多个进程都得以推进。并行指多个 CPU 核心同时运行多个进程此处不展开。并发是在单个 CPU 上通过进程轮换使用 CPU 实现宏观上同时运行的效果进程之间的轮换依赖上下文切换完成。上下文切换其本质是任务切换核心是 CPU 寄存器现场的切换。当多任务内核决定调度另一个任务运行时会保存当前正在运行任务的上下文即 CPU 寄存器中的所有内容。这些现场信息保存在该任务对应PCB中的内核栈中。保存完成后从下一个任务的内核栈中恢复它的上下文把数据重新载入 CPU 寄存器随后开始运行新任务这个过程就是上下文切换。寄存器是共享的而寄存器里的数据本质上是进程所私有的即是上下文数据。2.2 进程的组织在内核中task_struct进程描述符内部嵌入会多个链表节点结构体包含前后指针。依靠这些独立的链表节点同一个task_struct可以同时挂载到多个不同数据结构的链表当中。struct task_struct { **********//很多进程的属性 struct link node;//内嵌节点结构体 } struct link { struct link *prev;//前驱 struct link *next;//后继 }通俗理解就是 task_struct 是一个人 每一个 link 是这个人身上不同的挂钩 一个挂钩挂班级名单链表另一个挂钩挂运动会名单链表。人只有一个但可以同时在多个名单里。那为什么要如此设计呢首先进程在系统中会拥有多种属性不同内核模块需要按不同维度遍历进程调度器需要遍历就绪队列而内核管理模块需要遍历全部进程分开的链表节点可以满足不同模块的访问需求。 其次进程本体task_struct只需要保留一份不需要复制进程信息节省内存修改进程属性时只需要修改唯一的这份保证数据一致性。 最后进程状态发生变化时仅需要摘下或挂载对应的链表节点例如进程从就绪变为阻塞只需操作就绪队列对应的节点其他链表上的节点不受影响操作灵活且开销小。三、进程调度3.1 Linux调度器基础架构首先我们要了解prio_array_t也就是活跃队列、过期队列这两个进程数组内部包含三个核心成员nr_active、bitmap[5]和queue[140]。struct prio_array_t { nr_active; bitmap[5]; queue[140]; }第一queue[140]这是一个链表数组。下标 0~99 对应实时进程下标 100~139 对应普通进程。进程的优先级本质就是数组下标。调度普通进程时从下标 100 向 139 的顺序依次执行对应队列里的进程。数组的每一个元素都是一条对应优先级的就绪进程链表。找到目标优先级队列后队列内部按照 FIFO 的规则调度进程。第二bitmap[5]即位图数组。如果每次查找就绪进程都遍历全部 140 条链表开销会很大。于是把 140 个队列按每 32 个分为一组用位图标记队列内存在就绪进程则对应 bit 置 1无进程则置 0。调度时通过位运算快速定位到存在就绪进程的队列效率远高于线性遍历。第三nr_active用来记录当前这个prio_array_t内就绪进程的总数量。当nr_active为 0 时代表当前队列没有就绪进程可以直接跳过后续判断避免无效计算。我们将优先级链表等属性封装进prio_array_t结构体中并创建数组array[2]。数组的两个元素分别代表活跃进程队列array[0]和过时进程队列array[1]再通过*active和*expired两个指针分别指向它们。这里就有一个很疑惑的点了为什么要多余分成活跃队列和过时队列明明都是相同的构成。我们设想一种场景如果所有进程优先级都是 61但持续不断有优先级为 60 的新进程就绪那么优先级 61 的进程会持续被抢占永远得不到 CPU 执行。为了解决这类饥饿问题O (1) 调度器引入了活跃队列与过时队列的设计。在 Linux O (1) 调度器里runqueue 包含 prioity_struct_t array [2]分为活跃队列与过时队列调度器给进程分配不同时间片对活跃队列内进程分时调度进程时间片耗尽就移入过时队列当活跃队列全部进程时间片用完时交换两个队列指针以此避免进程饥饿。我们所说多个进程宏观上“同时运行”依靠的是 CPU 快速切换活跃队列中的进程产生并发效果并不是依靠频繁交换活跃、过时队列指针队列交换只是一轮调度周期结束时用来重新启用过期进程的机制。3.2 新旧调度方法比较老版 Linux O (1) 调度器基于时间片与双队列模型依靠active、expired队列切换解决进程饥饿使用bitmap和优先级链表做到 O (1) 查找就绪进程进程优先级决定时间片大小高优先级进程能获得更长的 CPU 运行时间。新版 CFS 完全公平调度器抛弃了时间片与 active/expired 双队列结构改用红黑树维护进程虚拟运行时间 vruntime始终挑选 vruntime 最小的进程运行nice 值不再控制时间片而是调整进程权重追求对所有进程的 CPU 使用占比公平。四、总结本文围绕 Linux 进程调度展开主要梳理了三个核心部分进程优先级、进程切换与进程调度。在进程优先级部分我们明确了 PRI 值代表进程优先级数值越小优先级越高NI 值nice 值用于修正优先级其取值范围被系统限制在 [-20, 19]且一般只能通过修改 NI 值来间接调整 PRI 值。在进程切换部分我们区分了并行与并发的概念并行依赖多个 CPU 核心同时运行多个进程并发则是在单个 CPU 上通过进程轮换实现宏观上的同时运行。进程轮换依赖上下文切换完成其核心是 CPU 寄存器现场的保存与恢复现场信息保存在进程 PCB 的内核栈中。此外进程通过 task_struct 内嵌多个链表节点可同时挂载到不同链表满足不同内核模块按不同维度遍历进程的需求。在进程调度部分我们介绍了 Linux O (1) 调度器的核心架构包括 queue[140] 优先级链表数组、bitmap[5] 位图加速查找以及 nr_active 就绪进程计数并通过活跃队列与过时队列的双队列设计解决进程饥饿问题。最后对比了新旧调度方法老版 O (1) 调度器基于时间片与双队列新版 CFS 调度器则改用红黑树维护 vruntime追求对所有进程的 CPU 使用占比公平。

相关新闻

电子鼻气体识别:ReLU+Adam将BP网络准确率从44.6%提升至93.3%

电子鼻气体识别:ReLU+Adam将BP网络准确率从44.6%提升至93.3%

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:52:42 阅读更多 →
TypeScript - TypeScript 结合打包工具

TypeScript - TypeScript 结合打包工具

一、webpack 1、引入 通常实际开发中我们都需要使用构建工具对代码进行打包,TS 同样也可以结合构建工具一起使用 2、使用步骤 初始化项目,创建 package.json 文件 npm init -y依赖配置 npm i -D webpack webpack-cli webpack-dev-server typescript ts-l…

2026/9/24 6:52:42 阅读更多 →
基于STM32的平衡球PID控制实战:从硬件选型到参数整定

基于STM32的平衡球PID控制实战:从硬件选型到参数整定

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 6:51:42 阅读更多 →

最新新闻

新疆靠谱的气动阀门厂家筛选名录:源头生产厂家实力盘点

新疆靠谱的气动阀门厂家筛选名录:源头生产厂家实力盘点

在新疆能源工程领域,管道阀门的适配性直接决定整个管网系统的运行稳定性,尤其是对安全性能要求极高的气动阀门,筛选靠谱厂家从来不是一件小事。不同于通用款阀门,气动阀门多用于易燃易爆的油气、化工、燃气工况,对产品…

2026/9/25 9:56:53 阅读更多 →
Atlas 300V 24G运算加速卡实战:YOLO部署全流程与调优

Atlas 300V 24G运算加速卡实战:YOLO部署全流程与调优

你可能已经发现,只要一搜“atlas”,出来的结果五花八门——有数据库中间件、有地图应用、还有一堆AI加速卡。但在“atlas部署yolo”和“atlas 300v 24g”这两个关键词组合出现时,事情就清晰了:大家问的基本是同一类东西&#xff0…

2026/9/25 9:56:53 阅读更多 →
Atlas 300V 24G部署YOLO实战:从推理加速卡选型到模型转换调优

Atlas 300V 24G部署YOLO实战:从推理加速卡选型到模型转换调优

最近后台有不少人问我同一个问题:Atlas 300V 24G 到底算不算运算加速卡?能不能拿来部署 YOLO?正好我手上这套视频目标检测项目用的就是 Atlas 300V 系列,模型从 PyTorch 的 YOLOv8 转成 CANN 的离线模型再上卡推理,整个…

2026/9/25 9:56:53 阅读更多 →
ax:基于CLI与Kubernetes的Agentic编排调度入口实践

ax:基于CLI与Kubernetes的Agentic编排调度入口实践

1. 从“ax”这个标题说起:一个被低估的Agentic编排入口第一次看到“ax”这个标题,很多人会以为是某个命令行工具的缩写,或者某个内部项目的代号。但把热搜词摊开来看——ax、agentic、orchestrator、Kubernetes、CLI——这几个词凑在一起&…

2026/9/25 9:56:53 阅读更多 →
Windows查硬盘序列号失效原因与四层可靠方案

Windows查硬盘序列号失效原因与四层可靠方案

1. 为什么百度搜“查硬盘序列号”90%的结果会把你带进坑? 我去年帮朋友重装系统,顺手想把旧硬盘的序列号记下来做资产登记。打开百度搜“如何查询硬盘序列号”,前五条全是教人用“设备管理器→磁盘驱动器→右键属性→详细信息→硬件ID”里扒…

2026/9/25 9:56:53 阅读更多 →
Xtreme ToolkitPro v17.2.0源码编译:MFC界面美化与高DPI适配实战

Xtreme ToolkitPro v17.2.0源码编译:MFC界面美化与高DPI适配实战

简介:资源包收录了Xtreme ToolkitPro v17.2.0完整源代码,面向有C开发经验、希望深入理解商业界面工具包内部实现并做二次定制的开发者,也适合正在学习MFC/WPF界面框架的进阶读者。包内共12111个文件,压缩后62.52MB,以h…

2026/9/25 9:55:52 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →