Linux------进程优先级与进程切换

目录

一、进程优先级

二、优先级与权限的区别

三、优先级的查看

四、进程优先级修改

五、进程切换

六、linux2.6内核调度队列与调度原理


一、进程优先级

首先我们得知道一个进程总是需要排队的,他一会在运行队列中排队等待运行,一会在设备的等待队列中排队,排队的本质就是在确认优先级

cpu资源分配的先后顺序,就是指进程的优先权(priority)

二、优先级与权限的区别

我们很容易把优先级和权限搞混淆。

优先级指得到申请资源的先后。

权限为是否能得到资源。

他们之间是先有权限,再谈优先级。

三、优先级的查看

进程的优先级其实就是PCB中的一个int字段,数值越小,优先级越大。这跟我们生活中买奶茶排号、医院挂号是一个道理,先叫的都是小号,先享受服务,后来的都是大号,晚一点享受服务。

Linux进程的优先级数据范围:60-99   

默认进程优先级:80

我们可以在命令行输入以下指令查看进程的优先级

ps -al

其中我们这里只需要关心 PRI 与 NI 这两项 

  1. PRI(priority):进程优先级
  2. NI(nice):进程优先级的修正数据

这里的NI即nice值,是Linux进程pcb中存放的一个值,他与PRI的公式如下

pri(新) = pri(老) +  nice 

这里的老pri不是指上次,而是值默认的pri,一般都是80

四、进程优先级修改

首先在命令行先输入 top 启动任务管理器,再在任务管理器中输入 r 打开重新调整renice值的任务框,此时需要先输入需要调整的进程的pid值。

 

将我们运行的死循环进程renice值修改为10 

此时nice值变为了10,同时PRI值变成了90。 

这样我们就完成了优先级的修改,数字变大了,也就是将优先级变低了。

这里我们尝试将优先级调低试一试

发现告诉我们修改失败,不能将优先级调低。此时需要使用 sudo 提权,如下

后面重复之前的操作,对优先级-10 ,此时优先级就变成了70。这里优先级不是从之前的90去-10,而是使用的默认的80 -10。

我们再次修改,让进程的优先级的nice值改为-100。发现进程优先级为60,nice值为-20,这是因为优先级的范围在60-99.系统不让你修改超过这个范围,如果超过了,就取最小值。 

小总结:nice值调整的最小为-20,超过部分统一处理为-20

              nice值调整的最大为19,超过部分统一处理为19

这样处理是为了让操作系统进行调度的时候,可以让每一个进程都得到调度否则如果用户随意更改优先级,会导致进程优先级过高,并且还可以一直调,刚运行完如果又调高,会让这个程序一直在运行,致使其他进程无法运行,进而优先级较低的进程长时间得不到CPU的调度,这也叫做进程饥饿。

五、进程切换

在学习进程切换前,我们得先了解以下概念

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

小总结一下,进程之间具有竞争性(因为成本控制,导致资源少,需要竞争)独立性 (该进程在运行时,该进程需要的资源只为他服务)

并行是多个CPU分别运行

并发是一个CPU通过进程切换,轮流让进程运行。

一般的用户都是用的单CPU,因此这里我们着重学习并发

首先,我们需知道每一个进程不是占有CPU一直运行的,每个一段时间(时间片),需要从CPU上剥离下来。不然你写一个死循环,一直运行该进程,其他进程还活不活了。Linux内核支持进程之间进行cpu资源抢占的。

同时cpu的速度是非常快的,比如说我们有10个进程,现在的时间片是1微秒,那么在一秒的时间,他可以将这是个进程轮流运行十万次,因此我们人的感知,是几乎感知不到的,就感觉这么多的进程都在同时运行,这样基于时间片的轮转式抢占内核就可以称作并发

并发,必须要考虑进程间的切换

cpu中有很多寄存器,比如eax,ebx,ss,ds,cs等等。通过这些寄存器,可以让数据进行暂时存储,同时寄存器的速度也是非常快的,在cpu内部快速的传递数据。

比如我们写了一个函数,返回类型为int,这时就会使用eax寄存器来保存该临时变量的值,你临时变量销毁就销毁了,无所谓,我寄存器在帮你擦屁股勒,最后给调用该函数的地方。如下代码,我们查看汇编就可以看到使用了eax寄存器。

再一个就是我们的进程内的代码需要不停的在函数之间跳转,此时也会用到pc或者eip来保存下一条指令的地址。

当我们进程在运行的时候,会使用这些寄存器的,我们的进程会产生各种数据,在寄存器中临时保存,如果有多个进程各个进程在cpu寄存器中形成的临时数据(进程硬件上下文),都是不一样的。

cpu寄存器硬件只有一套,而继承上下文数据有很多,是 1 对 n 的关系,因此当时间片到达,该切换下一个进程的时候,该进程的硬件上下文需要被保存到内存中,当我们下次再次运行该进程时,能够接着上次运行到的地方继续运行。

这个操作应该不难理解,这就相当于存档,我们玩幻兽帕鲁的时候,右上角会经常告诉我们存档中,这就是怕我们突然断网或掉线,如果不存档,就无法恢复到之前玩到的地方,我抓到的腾炎龙和阿努比斯没了,游戏体验就会大幅降低。

小总结:进程切换前首先工作要先将进程的硬件上下文保存到内存,进程重新运行前,需要将存放在内存中的进程硬件上下文重新写入到寄存器中,另外需要注意上下文保存的是寄存器的内容,而不是寄存器本身。

六、linux2.6内核调度队列与调度原理

如下是linux的运行队列具体内容

其中我们主要看蓝色框和红色框里的内容,其中queue具体为task struct *queue[140],是优先级指针数组,前面0-99是系统用的我们不关心,后面的100-139,对应了之前我们学习的60-99的优先级,操作系统将优先级相同的进程地址链入了对应的地方。如下所示

  • 上图中有红色和蓝色方框,为什么这里有两个方框呢? 

他们一个是active指针指向的,另一个是expired指针指向的。红色和蓝色方框内容相同。比如现在Linux启动了,目前有了10个进程,这10个进程都在active指向的内容中,他们在轮流运行,如果我现在添加了一些进程进去,被添加的进程不会被active指向,而是被expired指针指向,他要将active这些内容全部运行完了,才会再运行expired的内容。

  • 为什么会这样呢?

还是老样子,因为操作系统需要保证让每一个进程都能够被调度,如果我现在运行到80优先级的进程了,现在添加了一些60优先级的进程,如果只有一个数组,那么我就得返回运行这些优先级更高的进程,如果这些进程有很多,那么后面90优先级或者更低优先级进程会一直无法被调度。

但是这样也不合理啊,如果运行expired指向的进程时,有进程被添加进来,怎么办呢?此时需要往active添加进程呀!由于两个指针指向的内容都是一样的,我们运行完active里的所有进程后,可以通过swap(active,expired)来进行交换,这样就解决问题了。 

方框内不止有数组,还有nr_active与bitmap[5]。

nr_active是一个整形,是否为0来判断指针数组里是否有进程。

bitmap[5]是位图(C++实现位图 ),是int整形数组,一个int整形有32位,5个就有160位,足够140位的优先级访问。比如queue数组中下标120有进程,那么在bitmap中的121位会设置为1,借此来告诉操作系统这里有进程。虽然这样也需要循环遍历,但是我们可以以8位或者16位的速度进行是否为0判断,大大提高效率(毕竟进程有默认优先级,需要调优先级的进程较少)。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AcWing第141场周赛】AcWing 5464. 客人数量(A题)

文章目录 一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 一、题目 1、原题链接 5464. 客人数量 2、题目描述 二、解题报告 1、思路分析 按题意模拟,累加求和即可,最终输出结果。 2、时间复杂度 时间复杂度为O(n…

git命令远程仓库推送本地项目报错了,解决方案

如果你在使用git命令上传本地项目到远程仓库遇到了如下错误: Updates were rejected because the tip of your current branch is behind。n 别慌,肯定是你的远程仓库里面有原始文件,需要你提前进行一下合并操作,然后才能使用pu…

ES高可用架构涉及常用功能整理

ES高可用架构涉及常用功能整理 1. es的高可用系统架构和相关组件2. es的核心参数2.1 常规配置2.2 特殊优化配置2.2.1 数据分片按ip打散2.2.2 数据分片机架感知2.2.3 强制要求数据分片机架感知2.2.4 写入线程池优化2.2.5 分片balance优化2.2.6 限流控制器优化 3. es常用命令3.1 …

用Python Tkinter打造的精彩连连看小游戏【附源码】

文章目录 连连看小游戏:用Python Tkinter打造的精彩游戏体验游戏简介技术背景MainWindow类:职责:方法:Point类: 主执行部分:完整代码:总结: 连连看小游戏:用Python Tkinter打造的精彩游戏体验 在丰富多彩的游戏世界中&#xff0c…

【C++】C++入门 — 类和对象初步介绍

类和对象 1 类的作用域2 类的实例化3 类对象模型4 this指针介绍:特性: Thanks♪(・ω・)ノ谢谢阅读!下一篇文章见!!! 1 类的作用域 类定义了一个新的作用域,类的…

超级实用!Android Studio的10大神器插件,让你的开发效率翻倍!

超级实用!Android Studio的10大神器插件,让你的开发效率翻倍! Android Studio是一款功能强大的集成开发环境(IDE),专为Android应用程序开发而设计。它提供了丰富的工具和功能,使开发者能够轻松…

vulhub中Adminer远程文件读取漏洞复现(CVE-2021-43008)

Adminer是一个PHP编写的开源数据库管理工具,支持MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、Elasticsearch、MongoDB等数据库。 在其版本1.12.0到4.6.2之间存在一处因为MySQL LOAD DATA LOCAL导致的文件读取漏洞。 参考链接: https://gith…

Jenkins(本地Windows上搭建)上传 Pipeline构建前端项目并将生成dist文件夹上传至指定服务器

下载安装jdk https://www.oracle.com/cn/java/technologies/downloads/#jdk21-windows 下载jenkins window版 双击安装 https://www.jenkins.io/download/thank-you-downloading-windows-installer-stable/ 网页输入 http://localhost:8088/ 输入密码、设置账号、安装推…

Openresty+Lua+Redis实现高性能缓存

一、背景 当我们的程序需要提供较高的并发访问时,往往需要在程序中引入缓存技术,通常都是使用Redis作为缓存,但是要再更进一步提升性能的话,就需要尽可能的减少请求的链路长度,比如可以将访问Redis缓存从Tomcat服务器…

java社区养老年人服务系统springboot+vue

为了帮助用户更好的了解和理解程序的开发流程与相关内容,本文将通过六个章节进行内容阐述。 第一章:描述了程序的开发背景,程序运用于现实生活的目的与意义,以及程序文档的结构安排信息; 第二章:描述了程序…

12. Threejs案例-绘制颜色渐变圆柱体

12. Threejs案例-绘制颜色渐变圆柱体 实现效果 知识点 CylinderGeometry (圆柱缓冲几何体) 一个用于生成圆柱几何体的类。 构造器 CylinderGeometry(radiusTop : Float, radiusBottom : Float, height : Float, radialSegments : Integer, heightSegments : Integer, open…