Linux相关概念和重要知识点(10)(进程优先级、进程切换)

1.进程优先级

(1)为什么要有进程优先级

优先级的本质是获得某种资源的先后顺序,如排队买票这件事上排队的本质是在确认优先级,售票窗口就是要竞争的资源。为什么要有优先级?本质就是目标资源比较少,如果每个人都有一个售票窗口,那就不需要排队了,当然这是不可能的。

在计算机中CPU、设备的数量和进程的数量比起来都叫做少量,这也反映了CPU、设备资源是有价值的,毕竟物以稀为贵。进程的优先级竞争的是CPU资源。

注意优先级和权限的区别:优先级(建立在已经有权限的基础之上,就是谁先谁后的问题),权限(能还是不能的问题),没权限一定没有优先级的概念

(2)优先级的查看

每个进程的PCB里面就有优先级属性,优先级属性是由int表示的。Linux中优先级数字越小,优先级越高,类似于排名。

ps -al可以查看进程优先级属性

PRI(priority)代表当前进程的总优先级对应数字;NI(nice,细微的)代表优先级的微调数据PRI(最终优先级)= 默认优先级 + NI(优先级的修正数据)

在Linux中,我们每次创建的进程的默认优先级都是80(就算上次调度该进程PRI不是80,这次也依然默认是80),如果我们不显式NI修改,那么进程最终的PRI就是80。如果修改,那么PRI就会发生变化,就像上图的其中一个进程,NI == 19,那么它的PRI就是80 + 19 == 99。事实上NI的取值范围是-20 ~ 19,对应PRI为60 ~ 99共40种PRI取值。之所以规定优先级的微调最多浮动40,一方面是有相关统计和计算得出,一方面是防止进程优先级过高导致进程调度过于不公平,因为Linux终归到底是分时操作系统而不是实时操作系统,多个进程要有竞争性,保证在一个时间段里有多个进程同时推进而不是只处理一个进程。

在上面的图中,我们还可以关注UID,这是标志这当前用户的数字,因为用户名千奇百怪,作为属性性能开销过大,所以每个用户都会分配一个UID,ls -n就能以用户的UID形式显示了

每个用户在创建进程时PCB里面就含有用户的UID信息了,而每次的指令也是一个进程,所以当我们cd访问文件目录时就会尝试创建进程,PCB里面的UID就会和权限里的信息进行比对,从而实现根据不同身份进行拦截,这也是实现权限管理的关键。

(3)修改优先级

修改调整优先级本质是调整NI值

top可以查看当前系统的所有优先级信息

之后,使用r (pid) (回车) (微调值:-20 ~ 19)就可以实现NI值的修改,进而修改PRI

注意有的优先级修改需要root权限(特别是提高优先级),我们sudo即可

(4)优先级在runqueue中的体现

上面已经讲清楚PRI和NI组成优先级以及修改的方法。但问题是,优先级如何体现在runqueue中呢?

CPU每个核心都有一个调度器,分别管理着内存中的运行队列runqueue。为了体现优先级,runqueue采用多种数据结构来管理。以hash表为例,对于struct task_struct* queue[140],每个元素都是指针。假设前100个下标是给实时进程用的(实时进程不会被切换),还剩40个刚好分配给40种优先级状态。进程优先级是60-99,按照hash映射的规则存到对应位置种,其中为减少哈希冲突,采用哈希桶,即每个桶下面很多同优先级的进程。最后OS调度时根据数组相对位置调度进程。

2.进程切换

(1)时间片

Linux是一个分时操作系统,调度的公平性是这个系统的一个重要原则,包括NI的修改是有限的,也是基于这个原则来限制的。

进程是基于时间片来进行调度轮转的,当一个进程在时间片到的时候,不一定执行完了,但此时为了公平性它不能再执行了,CPU必须切换开始执行下一个进程的任务。对于这个没执行完的进程,OS需要保存它当前执行的位置,等到下一次重新调度时,再接着继续执行。但问题是:进程如何切换?当前执行的位置如何保存?

(2)寄存器

CPU内部存储数据的是寄存器(高速缓存L1、L2、L3也集成在CPU中,只不过速度慢一些,当然比DRAM还是快很多),常见的寄存器有eax、ebx、ecx、eflag、eds、efs、egs、cr0、cr1、cr2、ebp、esp、eip(pc)、ir...在上下文中,我们重点关心 eip(pc)、ir,它们在进程保存上下文数据中有重要作用。

(3)保存上下文数据是什么

对于时间片到了但还没有执行完的进程,OS要想办法将它当前执行的位置保存起来,方便下次继续执行,这个过程就是保存上下文数据以及恢复上下文数据。上下文数据就是代码和数据的相关执行情况。这类似于给学校请假时记录和回学校销假。

(4)eip(pc)、ir在保存上下文数据中的作用以及流程

当调度器调度到该进程时,内存中进程相关的代码和数据会被调用。CPU处理进程时,要存储执行指令相关的信息(当前执行指令、下一句指令的地址),这会产生临时数据,这是在CPU的寄存器中保存的。

eip存的是当前正在执行指令的下一条指令的地址。我们的代码(都被转为指令)执行的下一个位置是由eip(Extended Instruction Pointer,扩展指令指针)决定的。

ir是指令寄存器,保存就是CPU正在执行的指令eip告诉CPU控制器该读哪条指令,控制器就会根据地址去读,存到ir里。读有可能是到高速缓存中读(缓存中有该指令,称为缓存命中),否则只能到DRAM中读了(速度会慢一些)。每一次读取指令并保存到ir后,eip就会马上更新下一条指令的地址。

在ir保存指令且eip更新完成之后,CPU就会执行ir里面的指令,之后ir再次导入eip指定位置的指令,eip更新,CPU处理,以此类推......此外,还有eflag记录是否溢出,eax、ebx等用于保存变量。整个流程都是在CPU的控制器的管理下进行的。

当进程时间片到了之后,在进程被切换之前,OS会将eax、ebx、pc、ir...里面的数据保存一份(这个操作叫切走)。轮转后再次恢复进程时,OS会将最开始保存的寄存器里的数据恢复(这个操作叫切回),这时就能接着上次执行的位置继续执行。所有进程都有切走切回的操作,这样每次保存完上下文数据后,CPU就可以放心覆盖寄存器里面的数据了。

(5)TSS

每个进程都有一套自己的上下文数据,也叫寄存器数据。注意寄存器只有一套,而寄存器数据有很多。一套寄存器被多个进程共享使用,这也帮助实现了并发。

上下文数据(寄存器数据)保存在内存。我们可以简单理解为:进程的上下文数据保存到每个进程的PCB中的一个任务状态段的结构体TSS​​​​​​​就可以了,实际更加复杂。

在这里我们可以总结出:进程切换的核心是进程上下文数据的保存和恢复

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值