【Linux篇】你敢信?你的代码运行速度竟由这个‘隐形裁判’决定——进程优先级全解码
操作系统‘选秀现场’:进程如何靠优先级C位出道?
- 一. 进程优先级
- 1.1 基本概念
- 1.2 查看系统进程
- 1.3 查看进程优先级命令
- 1.3.1优先级的极值问题
- 1.3.2 相关概念
- 二. 进程切换
- 2.1 基本概念
- 2.2 时间片(Time Slice)概念:
- 三. Linux内核进程O(1)调度队列
- 3.1 活动队列
- 3.2 过期队列
- 3.3 active指针和expired指针
- 3.4 总结
- 四. 最后
在操作系统中,进程调度是资源管理的核心之一,它决定了不同进程在处理器上的执行顺序。而进程优先级切换则是调度中的关键决策点,它决定了哪个进程能够优先获得 CPU 时间。这一机制不仅影响着系统的响应速度和效率,还对多任务并发执行和资源分配产生深远影响。理解进程优先级的切换原理,不仅有助于优化系统性能,还能帮助开发者在设计高效应用时做出更合适的决策。接下来,我们将深入探讨进程优先级切换与调度的工作原理,揭开这一看似复杂过程的神秘面纱。
💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!
👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对Linux OS感兴趣的朋友,让我们一起进步!
一. 进程优先级
1.1 基本概念
进程优先级是操作系统调度算法中的一个重要概念,它决定了系统中多个进程执行的顺序。每个进程在操作系统中都有一个优先级,优先级越高的进程越容易获得 CPU 时间片,从而先于优先级较低的进程执行。通常,进程优先级的设定和调度策略是动态的,会根据系统负载、进程的紧急程度、等待时间等因素进行调整。
1.2 查看系统进程
命令格式:
ps - l
示例:
- UID:用户者的身份,访问任何资源都是通过进程访问,进程代表用户。
- PID:当前进程的唯一标识符。
- PPID:当前进程的父进程的唯一标识符。
- PRI:进程的优先级,默认60。
- NI:进程优先级的修改数据,nice值。
PRI越小,该进程的优先级越高,反之越低。
进程真实优先级 = PRI(默认) + NI。
1.3 查看进程优先级命令
命令格式:
先按top,进入后 -> 按r -> 输入进程PID -> 输入nice值
1.3.1优先级的极值问题
- Linux进程优先级极值范围:[60,99]
- Linux NI极值范围: [-20,19]
验证:
预备知识:进程真实优先级 = PRI(默认) + NI。
示例(如下图):
最小值验证
问题1:按上述公式PRI = 80+(-100)=-20,所以上述pid为1103842进程的PRI应该为-20,而实际上为60,所以进程优先级的最小值为60,实例中输入的NI值为-100,而实际为-20,同时也可以验证NI最小值为-20。
最大值验证:
问题2:按上述公式PRI = 80+100=180,所以上述pid为1103842进程的PRI应该为180,而实际上为99,所以进程优先级的最大值为99,实例中输入的NI值为100,而实际为19,同时也可以验证NI最大值为19。
1.3.2 相关概念
- 竞争(Race Condition):多个进程同时访问/修改共享资源(如内存、文件)时,因执行顺序不确定导致的冲突。
- 并行(Parallelism):真正同时执行多个进程(依赖多核CPU)。
- 并发(Concurrency):单CPU上“快速切换”进程,让用户感觉同时运行(时间片轮转)。
- 进程独立性(Isolation):进程拥有独立内存空间和系统资源,互不干扰。
上述概念了解一下即可,知道有这回事就行。
二. 进程切换
2.1 基本概念
进程切换(Process Context Switch)是操作系统调度机制中的一个重要过程,它指的是操作系统将 CPU 从当前正在执行的进程切换到另一个进程的过程。每次进程切换时,操作系统需要保存当前进程的状态信息(如寄存器的值、程序计数器、堆栈等),然后加载下一个进程的状态,恢复其执行环境。
保存当前进程的状态信息存在PCB中为tss(任务状态段)。
Linux内核源码(如下图):
知道就行了,后面会展开说,很复杂😂
一个进程不会一直占有CPU,进程会将他从CPU剥离下来。存在时间片这东西。
2.2 时间片(Time Slice)概念:
时间片是操作系统中用于多任务调度的一种机制,它定义了每个进程在 CPU 上运行的最大时间量。操作系统通过将 CPU 时间分成多个小片段,每个进程轮流获得一个时间片,在该时间片内执行任务。时间片用尽时,操作系统会触发进程切换,将 CPU 分配给下一个进程,从而实现多任务并发执行。
- 存在意义:通过时间片调度,操作系统能有效管理多个进程之间的资源分配,提升系统的响应能力和任务并发执行效率。
三. Linux内核进程O(1)调度队列
调度队列结构如下:
一个CPU拥有一个runqueue
- 如果有多个CPU就要考虑进程个数的负载均衡问题。
优先级
- 普通优先级:100〜139(我们都是普通的优先级,想想nice值的取值范围,可与之对应!)
- 实时优先级:0〜99(不关⼼)
3.1 活动队列
- 时间⽚还没有结束的所有进程都按照优先级放在该队列
- nr_active: 总共有多少个运⾏状态的进程
- queue[140]: ⼀个元素就是⼀个进程队列,相同优先级的进程按照FIFO规则进⾏排队调度,所以,数组下标就是优先级!
从该结构中,选择⼀个最合适的进程,过程是怎么的呢?
- 从0下表开始遍历queue[140]
- 找到第⼀个⾮空队列,该队列必定为优先级最⾼的队列
- 拿到选中队列的第⼀个进程,开始运⾏,调度完成!
- 遍历queue[140]时间复杂度是常数!但还是太低效了!
- bitmap[5]:⼀共140个优先级,⼀共140个进程队列,为了提⾼查找⾮空队列的效率,就可以⽤5*32个⽐特位表⽰队列是否为空,便可以提⾼查找效率!
3.2 过期队列
- 过期队列和活动队列结构⼀模⼀样
- 过期队列上放置的进程,都是时间⽚耗尽的进程
- 当活动队列上的进程都被处理完毕之后,对过期队列的进程进⾏时间⽚重新计算。
3.3 active指针和expired指针
- active指针永远指向活动队列
- expired指针永远指向过期队列
- 可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间⽚到期时⼀直都存在的。
- 没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了⼀批新的活动进程!
3.4 总结
在系统当中查找⼀个最合适调度的进程的时间复杂度是⼀个常数,不随着进程增多⽽导致时间成本增加,我们称之为进程调度O(1)算法!
四. 最后
在操作系统中,进程调度通过优先级来决定进程执行的顺序,优先级高的进程优先获得 CPU 时间。进程优先级分为静态和动态,动态优先级根据系统负载和进程紧急程度进行调整。进程切换是操作系统将 CPU 从一个进程切换到另一个进程的过程,保存当前进程的状态信息以便恢复。时间片机制通过将 CPU 时间划分为多个小片段,确保每个进程公平地获得执行机会。Linux内核使用O(1)调度算法,借助活动队列和过期队列,高效管理进程调度。调度的时间复杂度是常数,不随进程数量增加而增加,从而提升系统效率。
路虽远,行则将至;事虽难,做则必成
亲爱的读者们,下一篇文章再会!!! color{Red}亲爱的读者们,下一篇文章再会!! ! 亲爱的读者们,下一篇文章再会!!!