ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux系统篇(五),深入理解Linux进程优先级

Linux系统篇(五),深入理解Linux进程优先级

一,竞争,独立,并行,并发

竞争:系统进程数目众多,而CPU资源只有少量,甚至只有一个,所以进程之间是具有竞争属性的,为了高效完成热播我要,更合理竞争相关资源,就有了优先级

独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰

并行:多个进程在多个CPU下分别同时进行运行,这个称之为并行

并发:多个进程在一个CPU下采用切换的方式,在一段时间内,多个进程都能得以推进,称之为并发

二,基于时间片的分时操作系统

早期计算机是单任务,一个程序跑不完,后面程序只能干等,而现代Linux是典型的分时操作系统

2.1时间片是什么

内核为了让多个进程尽量实现在同时运行,会给运行队列中的每一个进程分配一段微小的CPU轮转执行时间,这个及其短暂的时间区域就叫做时间片(通常只有几毫秒到几十毫秒)

2.2时间片轮转机制的好处

基于时间片轮转机制,Linux的多任务运行呈现出一种独特的运行景观:

微观串行:在极短的几毫秒(一个时间片)内,CPU的核心依然是严格的单线程,串行的只执行某一个进程的指令

宏观并行:当一个进程的时间片耗尽,操作系统会立刻剥夺CPU使用权,强行将其推回队列排队,并把CPU切换给下一个进程,因为时间片极短且切换频率极高,就造成了所有程序在同时并行的错觉

三,进程优先级的基本概念

进程资源有很多,而CPU资源是有限的,为了保证系统高效,操作系统必须有一套机制来决定谁先运行,谁后运行,这就是进程的优先级

3.1区分:优先级和权限

权限:决定的是你能不能做某件事情,例如:普通用户能否读取root权限文件

优先级:决定你做一件事情的先后顺序,假设你已经具备了执行的权限,只是在时间节点上面进行排队

3.1.1UID

在Linux内核中,系统用来识别用户身份,划分进程归属的判定就是一串数字UID

内核对身份的数字化绑定:每当一个用户在终端启动一个程序时,内核在为其创建进程控制块(task_struct)时,会将该用户的UID直接写入其中,意味着,系统中的每一个进程,底层都有UID数字

UID的划分规则:

0:超级用户root的UID永远是0,最高权力

1000+现代Linux的发行版中,平台用户的UID是从1000之后开始累加

如何查看UID:在终端输入ps -l或ps -al,输出结果中保护的UID对于的数字,代表的就是该进程的拥有者是谁

-n选项,以数字形式返回,原本ll应该显示的是我们的用户名

3.2Linux下查看进程优先级

3.2.1,使用ps-l命令查看

在Linux终端中,我们可以通过输入ps -l(或ps -al显示所有用户)命令来查看当前终端下进程的详细列表和指标

F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S 1000 3214 3200 0 80 0 - 29115 do_wai pts/0 0:00:00 bash 0 R 1000 3521 3214 0 80 0 - 38312 - pts/0 0:00:00 ps

3.2.2需要注意的地方:PRI和NI

PRI(Priority 进程优先级):这是进程真正被CPU执行时的最终优先级指标

数字越小,对应的优先级越高,意味着越先被CPU执行

NI(Nice 谦让值):这是我们需要手动或动态调整的修正数据

它表示进程的谦让程度,Nice越小,表明进程越不想谦让,想要抢占更多CPU资源,从而拉低PRI,Nice值越大,说明越愿意谦让

3.3进程优先级计算公式

3.3.1动态计算公式

在Linux系统中,进程最终优先级PRI并不是一成不变的,而是由基准值和Nice值共同叠加计算出来的,计算公式如下:

PRI(最终)​=PRI(基准)​+NI

在标准Linux内核中,普通进程的默认基准优先级PRI通常固定为80

3.3.2Nice值对最终优先级的映射

当NI = 0 时:PRI = 80 + 0 = 80

当NI = -10时:PRI = 80 + -10 = 70,此时数字变小,优先级提升

当NI = 15时:PRI = 80 + 15 = 95,此时数字变大,优先级下降

Nice值为负数,PRI减小,优先级变高

Nice值为正数,PRI增大,优先级变低

3.4Nice值的取值范围与限制原因

3.4.1Nice的取值范围

为了防止某个进程无休止调整Nice从而彻底垄断或者搞崩溃系统,Linux内核对Nice的取值做了严格的界定:

Nice的取值范围 = 【-20,19】

总共只有40个级别

这意味着,普通进程对应的最高优先级是60,最低优先级为99

3.4.2为什么把Nice值的范围限制这么小

Linux这样设计的目的是为了防止进程饥饿

操作系统必须做到股票调度,如果用户允许无限度拉高或者降低进程优先级,那么高优先级恶意进程会死死霸占CPU资源,导致其他普通的后台进程,系统维持进程永远分配不到CPU时间片,会被长时间卡在队列里面

4,优先级的修改方式

优先级可以调整,不论是启动进程还是进程运行时

4.1命令行与系统调用修改方式

4.1.1命令行工具

nice命令:在启动进程时,指定其初始nice值

nice -n 10 g++ main.cpp -o main

(注:如果不指定-n参数,nice默认会把进程的 Nice 值设置为 10)

renice命令:在进程运行时,动态调整其nice值

renice -n 5 -p 1234

不需要root权限

sudo renice -n -5 -p 1234

需要root权限

4.2.1系统调用

需要包含以下头文件和函数原型

#include <sys/time.h> #include <sys/resource.h> int getpriority(int which, int who); int setpriority(int which, int who, int prio);

4.2.2通过top命令交互式修改

1.进入控制台:在终端输入top运行性能监视器

2.触发修改机制:在top界面中按下r进入renice调整模式

3.选择进程PID:

此时界面会弹出提示: PID to renice[default pid = 24300]

缺省参数即为当前top列表中默认选中目标进程PID

如果想要修改特定进程,手动输入目标进程PID

4.修改nice只:随后系统会提示Renice PId 25110 to value,此时就可以输入期望修改的Nice值

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进