Linux进程(四).进程优先级以及进程切换,进程调度

一.进程优先级

1.是什么?

进程优先级是得到CPU资源的先后顺序。

那么优先级和权限有何区别呢?

优先级是能够得到CPU资源,只是先后问题而已,而权限考虑的是能否得到资源的问题。

2.为什么要设计优先级?

原因在于CPU资源有限,要通过优先级去确定谁先谁后。

3.怎么办?

进程优先级是task_struct里的一个属性,是一个int数字。值越低,优先级越高。

①.知识点补充------uid

uid:即user id,OS识别用户是谁的东西,每个用户都有一个唯一的uid,这就是进程为什么访问文件的时候,OS准确识别出访问者是owner还是other还是所属组。

来说说是怎么识别的:

当查询某个进程的相关信息时,也会显示当前用户的uid,即显示派自己来做事的老大是谁:

创建文件时,文件也会储存三个角色的uid:

而访问文件的指令本身就是进程,那么指令这个进程也会存有uid,通过比对文件的uid和指令的uid,如果和文件哪一个角色的uid相等,那么就判定访问者是什么角色。

用户->bash(OS给每个用户一个bash)->将访问任务交给多个进程(指令)->每个进程完成自己的访问任务。

因而,进程就代表用户,就像杨金水代表朝廷管理江南织造局一样。

此处补充父父子子部分知识点不够此后再做讲解的部分

②.回归正题

在进程详细信息这个列表中,PRI就代表进程的优先级 ,它的默认值是80 ,这个值可以改变,但不建议改动。而NI是nice值,代表进程优先级的**修正数据,**通过更改NI,就可以更改优先级。

得出一个结论:

这里有个坑,每次调整优先级,都是从默认值开始,去加NI值,所以千万不要拿PRI那列的数字去加NI值。

同时,NI值是有范围的:-20,19

LinuxPRI默认值为80,所以实际优先级的范围是**60,99**

为什么要去设置一个范围呢?原因是为了进程得到CPU资源的公平性,得让每个进程不能等的太久。长期得不到资源的进程会有进程饥饿的现象出现。就像排队在食堂打饭,等太久人都饿麻了。

二.切换进程

1.知识点补充------竞争,独立,并行,并发

①.竞争

OS内的进程数量始终是要多余CPU的资源的,所以进程间必然发生竞争。为了高效完成任务,合理竞争资源,就有了进程优先级。

②.独立

就像任务管理器里有很多进程在使用CPU资源,将其中一个进程结束,并不会影响其他进行的运行。每个进程在使用资源期间,这些资源供其独享,多个进程之间互不干扰。至于如何做到独立性,我们后面的文章的谈到。

③.并行与并发

并发:一个CPU先服务一个进程,然后迅速断开,再服务另一个。

并行:多个CPU同时服务多个进程。

2.进程切换

①.死循环如何运行

每个进程都会被分配到一个叫时间片 的东西,这是个时间段,当CPU服务这个进程的时间超过时间片,就会停止服务,换句话说进程拥有CPU资源不是永久拥有的,而是在时间片这段时间内暂时被拥有,时间一到,CPU就会切换另一个进程,进行服务。所以进程拥有太多的数据或代码的话,是不一定能在一次服务里被执行完的。

而死循环进程并不会一直执行下去,直到内存被消耗完,卡死系统;当其运行时间超过时间片,CPU就会切换服务的进程。

②.浅谈CPU的寄存器

1.CPU内部存在多个寄存器,多个寄存器临时储存一个正在运行的进程的上下文数据

2.寄存器!=寄存器里的内容。

寄存器就是运输机本身,只有一份,寄存器里存的临时数据就是装在运输机里的东西,要么是坦克,士兵,大炮,要么混着来,反正不唯一,也不重样,运载的武器换了,但运输机还是它自己。

③.如何切换进程

Ⅰ.与大学生参军入伍的例子,类比出切换的过程:

进行一次保留,剥离,再恢复的过程,就是进行一次切换进程。

Ⅱ.具体切换的过程:

数据经拷贝以后存储在何处?

如何区分全新进程和已经调度过的进程呢?

三.Linux进程调度

切换和调度共同构成了调度器。

我们在上一篇文章梳理了调度队列如何处理阻塞的原理,但那是关于操作系统学科范畴,属于纸面的东西,这一部分将要从Linux底层的角度去了解调度。

1.前备知识

在了解整个底层之前:得明白我们正在使用的操作系统是分时操作系统 ,是基于时间片进行调度的,而不是当下谁重要,谁优先级就最高的实时操作系统。但Linux操作系统是具有一定的实时操作系统功能的,只是平时使用时被裁掉或被关闭了而已。

2.映射算法

queue140数组里有140个位置,每个位置都存储一个task_struct指针 ,前100个属于实时优先级,不考虑,剩余40个就刚好对应了分时优先级-20.19里的40个优先级的范围。

那么如何将越界的分时优先级映射到剩余40个位置里储存起来呢?

这40个位置的首个位置下标是100,60是默认值80 + 优先级最小值-20,用60作为被减数的原因是求一个偏移量:

3.调度规则

既然能玩映射,那么这个queue140本质是一个哈希表。

假如几个进程的优先级相同 ,那么就可以像哈希桶那样,将这几个进程全部链接在那个位置上。

那么就可以总结一下:在整个宏观的queue上,看优先级, 按照进程优先级(也就是顺着queue往下)来进行调度**,但需要逐个节点的去遍历,可能会出现遍历到的节点没有进程的情况,找到第⼀个⾮空队列,该队列必定为优先级最⾼的队列。在局部的同一个位置,即优先级相同时,按照先进先出的原则对链表上的进程进程调度。所以就要分两步,先挑队列,再挑进程。**

4.调度器如何快速调度?

按照以上的调度方式,调度器去寻找某个进程,在链表上的开销是O(1),在整个队列上的开销是O(N),那么总开销就是O(N),是比较低的,那么调度器可否快速挑选进程呢?

造成低效率的原因是,挑队列的时候我无法知道哪个位置是有task_strucrt的,因此需要在队列上从上往下按着优先级来逐个遍历队列元素。

这就不得不提runqueue里位于queue140上方的bitmap5了,这是个无符号整型的map,一个无符号整型的数是32位,那么5个就是160位,每位与runqueue上的元素一一对应,每个比特位无非两种结果------0或1,1就代表queue对应的元素存在task_struct,反之就不存在。所以挑队列时就可以根据map筛出有task_struct的位置,然后在这些位置中再挑进程。就能在O(1)的开销下挑队列。

那为啥是160个比特位,也就是5个无符号整型呢?原因是4个数128位没法覆盖包揽runqueue每个节点,6个数192位又过于浪费了。那么闲置的20个就不用了。

相关推荐
Elastic 中国社区官方博客32 分钟前
列式存储并不等同于列式数据库。Columnar 模式为 Elasticsearch 带来了什么
大数据·运维·数据库·elasticsearch·搜索引擎
fengkai45451 小时前
八、Docker详解4-5
运维·docker
智恒百亿2 小时前
RTX 5090 八卡服务器 vs RTX PRO 6000 整机:AI 推理、微调与渲染选型部署指南
运维·服务器·rtx5090
ManageEngineITSM2 小时前
DevOps和ITIL是什么关系?是替代还是互补一文讲清
java·服务器·资产管理·变更管理
DYWorker0012 小时前
Linux驱动子系统:DMA-Buf —— Consumer和Provider(008)
linux·驱动开发
雯宝3 小时前
Linux 内核函数集
linux
码少女3 小时前
Linux--多路转接之select
java·服务器·数据库
GeW4 小时前
从挂科到高分通过:RHCE快速拿证的10个提分技巧
linux
蓝胖的四次元口袋4 小时前
Docker Compose多容器编排与Nginx集群实战
运维·nginx·docker compose
懂软件的胡子个哥4 小时前
微信 API 消息回调怎么设计,才能避免丢消息和重复处理
运维·微信·架构·wechatapi·个人微信号二次开发