【Linux】进程切换与优先级

前言:

上文我们讲到了操作系统与Linux中进程的状态【Linux】进程状态-CSDN博客

本文我们来讲进程的优先级、以及进程的切换

进程优先级

什么是优先级?

CPU中资源是有限的,而进程的数量一定是远大于CPU资源的,所以优先级是进程得到CPU资源的先后顺序优先级也是进程的属性之一,保存在PCB中。

优先级的实现

优先级是进程的属性之一,保存在PCB中。

优先级中PCB中用整型表示,其值越小表示优先级越高,反之优先级越低。

优先级是可以被修改的。但考虑到时间片的分时操作系统,以及公平性,优先级不能出现大幅度的修改。

如上图,我在Linux中使用执行查看当前正在运行的进程信息。可以看到红圈这两个值:

PRI:表示进程的优先级,其默认值是80

NI:表示进程优先级的修正数据,称为nice值

优先级的修改:是通过nice值的修改实现的,既最终的优先级 = PRI + NI

如图,通过renice指令来修改进程的优先级后,我们再次查看进程信息可以发现第一个被修改的进程NI变成了10最终的优先级变成了90。 说明默认值是不改变的,优先级修改是通过nice值的修改而实现的

补充:UID

如上图,我们可以看到第三列有一个叫做UID的。那什么是UID呢?

UID:user id,表示用户标识符

在linux中任何访问资源的操作都是进程实现的,进程代表当前的用户。那系统是如何判断当前进程访问的权限的呢?

其实就是通过UID实现的:通过进程中的UID与文件的UID相比较,就可以判断出这个进程的访问权限是拥有者、所属组还是other

优先级的极值

如图可知,优先级的范围是[60 - 99],而nice值的范围是[-20 - 19]

优先级范围设置的并不宽泛,因为优先级范围设置过大会导致,优先级低的进程长时间不能获得CPU资源,进而导致:进程饥饿

进程关系

**竞争性:**进程与进程之间是存在竞争关系的。CPU资源有限,为获得CPU资源,为了高效完成任务,更合理的竞争相关资源,便有了优先级。

**独立性:**多进程运行时,各个进程之间是独享资源的,互不干扰。

**并行:**多个进程在多个CPU下,同时运行。

并发: 多个进程在一个CPU下不停的切换运行,在一段时间内,让多个进程不断推进。

进程切换

进程的切换讨论范围在长代码与死循环代码,因为较短的代码一瞬间就执行完毕了,没有切换这一说法

死循环进程

死循环进程一段占用CPU执行代码,会一直占用CPU吗?

并不会,因为在计算机是分时操作系统,在进程执行的过程中存在"时间片"每个进程都有其适合的"时间片"(本质其实就是计数器),时间片达到时,进程就会从CPU上剥离下来

所以死循环并不会一直占用CPU。

CPU中的寄存器

CPU中存在各种各样的寄存器,用于保存 当前正在运行进程的各种临时数据

寄存器就是CPU内部的临时空间

寄存器!=寄存器中的数据

如何切换

A进程占用CPU执行完一个时间片后,要被剥离CPU,进而执行下一个进程。

那么当再次执行A进程时,应该从上次执行位置开始继续向下执行。 这就意味着剥离时,需要当前进程把自己的上下文记录下来,以便于下一次继续执行。

进程上下文保存到了哪里呢?保存到了进程task_struct的TSS中(TSS:任务状态段),下一次执行时,之间覆盖CPU中的寄存器内容即可

对于以及执行过的进程才需要记录上下文,对于之前还没有执行过的继承无需记录,及其将寄存器内容初始化即可。

Linux中真实的调度算法:O(1)调度算法

如上图,runqueue是一个运行队列 ,且一个CPU只有一个运行队列。

queue[140]

我们先来介绍一下queue[140] :它的数据类型是 struct task_struct*

复制代码
struct task_struct* queue[140]

queue一共有140个元素**,一个元素就是一个进程队列,其下标映射了优先级** 。前100个元素代表实时优先级(我们不关心)后40个代表我们上面所讲的普通优先级

我们之前讲到优先级的范围是:60~99,那对应在queue中的下标表示就是:100~139 (x - 60 +100)。比如优先级为64的进程就会链接至下标为104的节点下,多个优先级一样的进程都会被依次链接在同一个进程队列中

bitmap

bitmap[5]用于在queue中快速查找进程

bitmap的数据类型是 unsigned int,一个元素有32bit,一个有5个这样的元素。

用bit位记录进程信息,0表示没有进程,1表示有进程。从下标0开查询,一次性查询32个位置,并从最后一个"1"开始调用进程(既优先级最高的进程位置)。

nr_active

记录进程的个数,当进程个数为0时,不在使用bitmap查询进程。

过期队列与活跃队列

在图中我们可以看到有两个一模一样的队列结构(蓝框与红框),并由两个指针分别指向:active(活跃)、expired(过期)。

active指向的队列叫做活跃队列,反之另一个叫过期队列

活跃队列上的进程是要占用CPU资源,执行代码的。当活跃队列上的进程执行完一个时间片后,会放到过期队列中的相应位置上(优先级对应的位置)。当活跃队列上的进程全部执行完时,active指针与expired指针交换:过期队列再次变为活跃队列,继续执行之前的进程

Linux中进程切换的整体过程

1.由bitmap在活跃队列中查询进程位置(优先级最高进程的位置)

2.依次占用CPU资源,执行相关进程

3.时间片耗尽,记录上下文后从CPU上剥离,并链接至过期队列中

4.直到活跃队列中没有进程,指针交换,再次循环至第一步

补充:

如果新建了一个进程,是插入活跃队列还是过期队列?

:活跃队列,新创建的进程应该尽快获得执行机会,而不是放入已经执行过的过期队列中等待下一次的调度

相关推荐
FIT2CLOUD飞致云19 分钟前
支持MySQL、PostgreSQL和Redis集群部署,1Panel开源面板v2.0.5版本发布
运维·开源
南玖yy1 小时前
Linux 桌面市场份额突破 5%:开源生态的里程碑与未来启示
linux·运维·服务器·汇编·科技·开源·gradle
Star在努力1 小时前
14-C语言:第14天笔记
c语言·笔记·算法
泰勒疯狂展开1 小时前
Linux研学-MySQL安装
linux·mysql·adb
霜绛2 小时前
机器学习笔记(三)——决策树、随机森林
人工智能·笔记·学习·决策树·随机森林·机器学习
Vesan,3 小时前
【Linux/Ubuntu】VIM指令大全
linux·ubuntu·vim
苹果醋33 小时前
iview中实现点击表格单元格完成编辑和查看(span和input切换)
运维·vue.js·spring boot·nginx·课程设计
丨千纸鹤丨3 小时前
高可用集群Keepalived
linux·服务器·网络
☞下凡☜5 小时前
C语言(20250722)
linux·c语言·开发语言
hweiyu005 小时前
开发运维DevOps(附电子书资料)
运维·devops