LINUX入门篇【11】---进程篇【3】---进程优先级,进程切换,进程调度

前言:

有了前面知识点的铺垫,本篇我们将围绕进程的三个方面来展开,即进程优先级,进程切换以及进程调度的问题,这里的进程调度其实本质就是CPU是如何去调度进程的。

进程优先级:

优先级的概念:

让我们先考虑这样一个场景,当我们中午去食堂排队买午餐的时候,我们的队伍是分为先后的,前面的人优先选择自己爱吃的,后面的人则需要等到前面的人选完才能轮到自己选。但是排队的所有人都要购买午餐的权利,只是先后买到的问题。
由此,我们便得出了在OS中进程排队的本质:
在资源不足的情况下,软硬件资源为少数,而进程是多数的,因此,在这种情况下,便有了优先级的概念。
那何为优先级呢?
即是得到某种资源的先后顺序
那优先级和权限有什么区别呢?他们两个如何区分呢?
权限是你是否有得到某种资源的能力,而优先级是你已经默认有了获取某种资源的能力,只不过是先得到还是后得到的区别
有了上面的概念的区分,我们下面来看看在实际的操作系统中是如何实现优先级的。

操作系统中优先级的实现方式:

优先级也属于PCB的一个数据段,和我们的状态一样,优先级也由一个整型变量来控制,对应的这个数值越小,它的优先级就越高。
反之,优先级就越低。
在LINUX中,进程的优先级的数值范围为60-99,一共40个等级划分,而LINUX中默认的进程的优先级都是80
我们在LINUX想要显示优先级,可以用指令ps -al来执行,即可以展示关于进程的更加详细的信息(其中的 l 代表更详细的意思,而a代表全部)
如下图:
在这里插入图片描述
图中的PRI即代表优先级的意思(priority),但是,默认的PRI都是80,那怎样体现优先级的先后呢?
LINUX是支持动态优先级调整的,如上图所示,你会发现,进程信息中还有一个NI值(nice值),我们默认的80的PRI是不会被修改的,本质上我们是利用PRI和NI的一个混合运算得到一个进程的优先级的,公式如下:
PRI(新)=PRI(默认80)+nice调整值
没错,根据公式,我们的PRI是不会变化的,一直是80默认,通过调整NI来调整优先级。
那如何调整NI值呢?其指令如下:
1.首先top打开任务管理器
2.输入r(renice)即修改NI值的指令
3.然后输入你要修改的进程的pid
4.然后重新输入新的要修改的NI值即可

如下图:
在这里插入图片描述
需要注意的点:
1.LINUX中,PRI默认都从80开始,不会记录上一次的PRI。
2.NI的取值范围为-20到19,也就是80减到60和加到99的临界情况,超出这个范围的数值,一旦超出,一律按照边界值处理,比如我NI值设为100,它也会自动将NI值设为19而不是100,不会超出范围。同理,NI值为-100,也会按照-20处理,不会超出范围

优先级的意义:

看了LINUX的优先级设置方法,或许有人会问:为什么要把优先级限定在一定的范围内呢?
这是由于OS在调度的时候,它需要较为均衡的让每一个进程都被均衡的得到调度,如果允许用户任意修改,则容易导致优先级较低的进程较长时间都得不到CPU资源来运行,这种现象又称为进程饥饿。故我们设置的级别为60-99,40位,导致区间进程的优先级相对固定。
因此,进程优先级的意义是:
让进程对于资源的调配更加合理,重要的进程优先运行,其次的进程后面运行,同时由于区间差距为40位,故优先级的差距不大,导致进程饥饿的问题得到解决。

其他的优先级指令:

1.nice指令
2.renice命令:与top一样,在进程启动时使用
3.LINUX系统调用,更改获取优先级,getpriority/setpriority

进程切换:

其他的概念:

1.竞争性:系统的进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争关系的,故为了高效完成任务,更合理竞争相关资源,便具有了优先级,
2.独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰
3.并行:多个进程在多个CPU下分别同时进行运行,称之为并行
4.并发:多个进程在一个CPU下采用进程切换的方式,在一段时间内,让多个进程都得以推进,称之为并发。

注意的一些细节:
1.首先区分一下,并行和并发的不同点,从CPU角度上,并行是多个CPU同时进行多个进程的,而并发是一个CPU分别切换进行多个进程的运行。
2.不要把并发理解为CPU同一时间内同时运行多个进程,本质上是先后切换进行的,只是这个时间非常快,在人的感知里就相当于同时在推进,因此叫并发。

因此,我们接下来详细讲讲进程切换的问题:

对进程切换的理解:

1.时间片:

首先注意,任何一个进程不是占有了CPU就一直运行,每隔一段时间,就会自动被从CPU上剥离下来,我们把这个进程在CPU上运行到被剥离出CPU的这段时间称之为时间片。
而LINUX内核是支持进程之间进行CPU资源抢占的,它的内核的本质是一种基于时间片的轮转,抢占式内核,根据每一个时间片的时间差去切换进程,故涉及到并发,则并发的过程中是一定涉及到进程间的切换的。

2.寄存器:

在我们的CPU硬件中存在着很多寄存器,比如eax,ebx,edx,ss,ds,cs,gs,fs,ebp,esp,eip,status,reg,cro~cr4等…
1.我们的函数内定义的栈的临时变量,在函数调用完就销毁的前提下,可以返回给外部,靠的就是eax寄存器将数据存储起来,为数据充当临时空间
2.为什么程序/进程,会知道我们当前程序运行到哪个位置了呢/它是如何做到函数跳转的呢?
这正是因为CPU内,有eip程序计数器,它会保存下一条指令的地址。
因此我们可以总结出:我们的进程在运行的时候,会使用寄存器,我们的进程运行的过程中会产生各种数据,这些数据都会由寄存器临时保存起来,不同的进程,CPU寄存器内的临时数据都是不一样的,我们将这些临时数据称为硬件上下文。
CPU硬件只有一套,但是寄存器可以存储的数据就不止一套了。
因此我们要明确,寄存器是硬件,而数据是逻辑的产物,寄存器!=寄存器里的内容。

寄存器里面的内容是可以随时更换的,但寄存器硬件只有一套。

3.进程切换的具体过程:

由上面的知识我们知道,一个进程的数据是由寄存器来保存的,那么在进程切换的时候,数据又是怎样保存下来为下一次运行做准备呢?
首先,所有的保存,都是为了恢复。进程保存数据也是为了下一次运行做准备。
而进程切换的本质就是将数据由硬件先保存到内存中,也就是用来管理进程属性的PCB中,再由内存中返回给硬件从而继续运行。
详细的切换过程如下:
一个进程倘若没有开始运行,则它会直接将数据拿到CPU上去跑,当涉及到进程切换的时候,CPU中的寄存器按顺序将寄存器中的数据拷贝到这个进程的PCB对应的数据段成员变量中,而后进程的PCB去执行其他调度,切换另一个进程交由CPU处理,而对于已经由CPU运算过一部分的进程,再次交给CPU运算,则会先将PCB中的数据,再按照顺序交给CPU的寄存器,其中也包括eip程序计数器等一系列寄存器,故此进程会从上一次切换的位置继续向下进行,这便是进程切换的过程如下图所示:
在这里插入图片描述

同时要强调一点的是,PCB的数据是以覆盖的方式把数据传给PCB的,同理寄存器传给PCB也是同理,不要担心数据丢失的问题,因为覆盖之前一定要首先对数据进行保存或者更新。

进程调度:

进程优先级,进程切换这些关于进程的知识点讲完了,下面我们来看看CPU是如何去调动我们的进程的。
我们以LINUX2.6为例,来看看它的调度队列是怎样的,如下:
在这里插入图片描述
从图中我们会看到,LINUX2.6的调度队列中存在着由红笔和蓝笔画上了两个一模一样的结构,在这个结构里包含三个成员:
1.一个状态标识变量nr_active
2.一个位图bitmap[5]
3.一个队列queue[140]

我用这张图让我们看懂我们的调度原理:
在这里插入图片描述
首先我们得queue数组是一个以PCB指针存储起来的数组,也就是说,它的每一个成员都是一个PCB结构体指针,在每一个结构体的后面去链接进程,前0-99是实时优先级,而100-139对应的就是我们的60-99正好40个优先级,数据的访问会从下标小的位置开始依次向后进行,故我们的优先级是越小优先级越高。
而在整个调度队列中还维护了两个指针voidactive,voidexpired,他们分别对应着我们的两个队列:活跃进程队列和过期进程队列
为了防止无限制的进程优先级高得进程得不断插入,导致后续得进程永远无法被执行,从而破坏了进程优先级的平衡性,LINUX2.6采取了双队列交替运行队列的方式,其中一个为活跃进程队列,另一个为过期进程队列,当活跃进程队列正在运行进程的时候,新增加的进程不论优先级都会被填入到过期运行队列中,不影响活跃队列的执行,当活跃进程队列的进程都被执行完后,此时的过期进程队列已经装配好了新的进程,这个时候active和expired交换指针的指向,让活跃变过期,过期变活跃,这个过程循环往复,两个队列交替运行进程,就保证了优先级的相对平衡性,不会有进程饥饿的情况发生。
而所谓的抢占,其实就是将过期队列的进程链接到活跃进程中优先运行。

位图成员:

在进程队列中还维护着一个位图成员bitmap[5],它是一个含有五个元素的整型数组,它的目的是快速锁定下标从而执行进程,我们找进程就不用再遍历queue去找了,而是通过位图去直接访问下标执行对应的进程,5个整型就是160个bit位,因此,利用二进制,从最右端开始位操作移动,遇到为1的说明此位数对应的下标上有进程要执行,而根据二进制的特点,我们可以8个一组或者16个一组去查看1的情况,这个要比遍历快很多,这种方法便是O(1)查找法。

因此,我们来总结一下CPU调度的具体流程:
首先访问active队列,查看nr_active的状态是否为1,为1说明有进程在队列中,然后通过位图锁定对应的下标,进入queue中直接根据下标去访问对应的进程队列从而执行相应的进程

最后我想提出的一个问题是:
我们之前说CPU维护着一条运行队列,协助调度,在这里我们有学到了调度队列中有两个队列,他们的关系是怎样的呢?
首先CPU维护着一条运行队列,这条队列在LINUX2.6中的实现方式是通过两个进程队列协助开始的,也就是说,两个进程队列是运行队列的一种实现方式,这便是他们的关系,不要混淆

总结:

本篇文章我们系统总结了进程优先级,进程切换,进程调度的问题,我希望结合前两个进程篇的知识,我们把整个进程在OS中的工作方式系统的去梳理一遍,保证每一个逻辑都是清晰的,有模糊的地方就去重新查看文章的细节,进程将对我们使用计算机的时候的一些现象有了更加合理的解释,所以,更希望大家在使用计算机的时候刻意去尝试推测某个软件所处的状态,从而进一步深化我们的进程知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/199877.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

matlab配置

matlab配置 windowslinux挂载安装MATLAB windows 按照这里一步步配置就行( 移动硬盘中软件备份中自取) linux linux配置步骤 挂载 sudo mount -t auto -o loop /media/oyk/Elements/ubuntu/MATLAB/R2017a_glnxa64_dvd1.iso ./matlab/安装MATLAB 挂载完成后,先…

JS之Object.defineProperty方法

给对象添加属性的方法有许多,这次让我为大家介绍一种给对象添加属性的静态方法吧! 语法:Objcet.defineProperty(对象的名称,“添加的键名”,{value:键值}) const obj {name:"张三",age:18}// 我…

MySQL索引使用总结

索引(index) 官方定义:一种提高MySQL查询效率的数据结构 优点:加快查询速度 缺点: 1.维护索引需要消耗数据库资源 2.索引需要占用磁盘空间 3.增删改的时候会影响性能 索引分类 索引和数据库表的存储引擎有关,不同的存储引擎&am…

广州华锐视点:基于VR元宇宙技术开展法律法规常识在线教学,打破地域和时间限制

随着科技的飞速发展,人类社会正逐渐迈向一个全新的时代——元宇宙。元宇宙是一个虚拟的、数字化的世界,它将现实世界与数字世界紧密相连,为人们提供了一个全新的交流、学习和娱乐平台。在这个充满无限可能的元宇宙中,法律知识同样…

docker镜像原理

什么是镜像 容器解决应用开发、测试和部署的问题,而镜像解决应用部署环境问题。镜像是一个只读的容器模板, 打包了应用程序和应用程序所依赖的文件系统以及启动容器的配置文件,是启动容器的基础。镜像所打 包的文件内容就是容器的系统运行环…

迷你洗衣机哪个牌子好又实惠?口碑最好的小型洗衣机

不得不说洗衣机的发明解放了我们的双手,而我们从小到大就有这个意识,贴身衣物不可以和普通的衣服一起丢进去洗衣机一起,而内衣裤上不仅有肉眼看见的污渍还有手上根本无法消灭的细菌,但是有一款专门可以将衣物上的细菌杀除的内衣洗…

界限与不动产测绘乙级申请条件

整理一期关于测绘资质界限与不动产测绘乙级资质的申请要求 测绘资质是由测绘资质主管部门自然资源部制定的 想要了解标准、正规的申请条件,可以到当地省份的政务网搜索测绘资质办理相关标准(例如下图) 1、通用标准 http://gi.mnr.gov.cn/20…

vue3中的setup()函数详解

​🌈个人主页:前端青山 🔥系列专栏:Vue篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-setup()函数 目录 setup()函数 1.1 基本使用 1.2 访问 Prop 1.3 Setup的上下文 1.4 与渲…

【古月居《ros入门21讲》学习笔记】16_tf坐标系广播与监听的编程实现

目录 说明: 1. 实现过程(C) 创建功能包(C) 创建tf广播器代码(C) 创建tf监听器代码(C) 配置tf监听器与广播器代码编译规则 编译并运行 编译 运行 2. 实现过程&a…

CCFCSP试题编号:202109-2试题名称:非零段划分

用差分法 #include<iostream> #include<algorithm> #include<cstring> using namespace std;const int N 500000; const int M 10000; int a[N 2 ] { 0 }; int d[M 1] { 0 };int main() {int n;cin >> n;for (int i 1; i < n; i){cin >&g…

泛微E-Office SQL注入漏洞复现

0x01 产品简介 泛微E-Office是一款标准化的协同 OA 办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 0x02 漏…

数组filter()方法的使用

输入价格后失去焦点就展示符合条件的商品&#xff0c;没有符合条件的商品就弹框提示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-…

在ubuntu系统安装SVN服务端,并通过客户端进行远程访问

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

Python变量及其使用

无论使用什么语言编程&#xff0c;总要处理数据&#xff0c;处理数据就需要使用变量来保存数据。 形象地看&#xff0c;变量就像一个个小容器&#xff0c;用于“盛装”程序中的数据。常量同样也用于“盛装”程序中的数据。常量与变量的区别是&#xff1a;常量一旦保存某个数据…

自写一个函数将js对象转为Ts的Interface接口

如今的前端开发typescript 已经成为一项必不可以少的技能了&#xff0c;但是频繁的定义Interface接口会给我带来许多工作量&#xff0c;我想了想如何来减少这些非必要且费时的工作量呢&#xff0c;于是决定写一个函数&#xff0c;将对象放进它自动帮我们转换成Interface接口&am…

oracle免费资源 终止实例 以及新建一台实例的折腾记录

事情的背景是这样的&#xff0c;我的一台oracle小鸡&#xff0c;不太好用的样子&#xff0c;有时候SSH连不上&#xff0c;有时候莫名其妙卡住。所以我就想把它重新安装一下系统&#xff0c;恢复成最初的样子。 然后在网上查资料&#xff0c;是有办法把系统重装一下的。但是略微…

numpy知识库:np.random.randint()用法及其使用场景举例

randint函数解析 import numpy as np# 【随机】返回[0,5)范围内的一个整数 # [0, 5) --> 左闭右开区间 int_a np.random.randint(5) # int_a 可能为 0、1、2、3、4 int_a np.random.randint(low5) # int_a 可能为 0、1、2、3、4# 【随机】返回[1,5)范围内的一个整数 int_…

分布式事务-两阶段提交2PC

2PC协议就是两阶段提交&#xff0c;用来解决分布式事务&#xff0c;分为两个阶段&#xff0c;分别为Prepare和Commit&#xff0c;也是PC由来。 第一阶段Prepare 提交事务请求 如图所示&#xff0c;主要流程有以下三个方面 询问&#xff1a;事务协调者(Manager)向所有的事务参与…

如何拥有免费的docker镜像仓库

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 hello&#xff0c;伙伴们&#xff0c;最近在研究devops的事情&#xff0c;发现了很有意思的东西。 就是我们所有…

基于SSM的电商购物网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…
最新文章