一、前言

进程优先级是操作中的一个重要概念,我们知道 一个 CPU 只能同时运行一个进程,而进程是由很多个的,所以需要存在进程优先级来确定进程获取 CPU 资源的顺序。那么话不多说,开启我们 进程优先级 的话题。

二、优先级的基本概念

什么是优先级?

在日常生活中,我们有很多排队的场景公路上等红灯在医院挂号或者是在食堂吃饭等等,但是我们在公路上救护车可以无视红灯医院里急诊病人可以优先挂号,以及食堂里老师肆意的插队… 

这些需要排队的事物,就可以看作进程,而像救护车急诊病人,以及食堂的老师等等,这些都是具有优先权的象征,为什么要有优先权呢?一定是有更重要的事情去做。

所以,此时就可以延申到 进程 ---- 的优先级是什么?

  • 进程要访问某种资源,进程通过一定的方式(排队),确认享受资源的先后顺序 

相信细心的你也发现了,优先级不就是我们前面学习的 ---- 权限吗?

  • 其实 优先级 和 权限 是有区别的:权限决定的是 --- 能不能的问题,而优先级是决定  --- 先后顺序的问题

 为什么要有优先级? 

 如果我们食堂的窗口远大于人数,如果我们自习室里的座位非常多,人却非常少,我们是不需要排队的,也就是说,当资源充足的时候,我们并不需要排队

 --------------所以优先级产生的本质是因为 ----- 【资源相对比较少】

所以呢,优先权高的进程有优先执行权利,有了优先级;才能使得一些重要的进程被率先执行

三、如何查看并修改 --- 进程优先级

知道了进程优先级的基本概念后,我们来Linux中看看它到底是个什么东西呢?

  • 我们可以对 运行起来的进程 使用下列指令去查看其优先级
ps -al

此处我们要关注的是以下几个重要信息:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的nice值

PRI and NI 

 那我们重点来讲解一下这两个信息值

  • 对于 PRI 还是比较好理解的,即 进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  • 那 NI 呢? 就是我们所要说的 nice 值了,其表示进程可被执行的优先级的修通俗简单一点来讲呢,就是进程的 nice 值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。

为了更直观的看到优先级,我们可以执行下面的代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
 
int main()
{
	while(1)
	{
		printf("this is a process, pid=%d\n", getpid());
		sleep(1);
	}
	return 0;
}

PRI

我们让改程序跑起来变为进程,我们使用如下命令查看 进程属性

ps -la#显示当前用户的所有进程

我们看到,横着 的 紫色 框是我们启动的进程竖着的 紫色 框有一栏叫做 PRI 的数值,其实 PRI 就是 priority ,优先权的意思。 

struct task_struct
{
	int PRI;//优先级
	//...
}

而我们运行自己写的程序,查询改进程的权限为80,这也就说明 Linux下进程的优先级本质就是数字

其实Linux下优先级是可以被修改的,修改范围为 [60, 99] 这40范围内,且 进程的默认权限值是80而优先级 数字越小,表示该进程的 优先级越高! 


NI

我们清楚了进程的优先级是什么,以及为什么,接下来我们看一下到底该怎么做? 

运行上面的程序,打印出进程的pid,使用 top 命令进入到 Linux任务管理器: 

top#进入任务管理器

  • 接下去按下 R/r 之后,就会跳出来下面这句话,这里的 renice 指的就是要重新修改进程,此时 shell 正在等待我们输入进程的 PID 值,那我们就可以输入上方的 5479
PID to renice [default pid = 1]

  • 然后呢,我们看到 shell 又在等待我们输入需要更改的 nice 
  • Renice PID 25761 to value
    

  • 这个时候再使用ps查看,就会发现进程的PRI这一项变为了90,但是我们发现,不仅仅是PRI这一栏变了,还有一栏叫做 NI 的值也变了,而且还刚刚好是我们输入的数值!

其实,Linux系统支持用户调整优先级,但并 不是让用户直接修改 pri 值,而是修改 nice 值。而 nice 值 不是 优先级,而是 优先级的 修正数据

  • 所以真正的优先级应该是:pri = pri(old) + nice ;old指老的优先级
  • 所以我们刚刚 修改的并不是优先级,而是nice值

优先级极限测试

进程的优先级真的只能在 [60,99] 这个范围呢移动吗?如果不相信,我们可以来做一下极值测试:

进程的优先级真的只能在 [60,99] 这个范围呢移动吗?如果不相信,我们可以来做一下极值测试:

  • nice值变为19,pri变为99,就是我们给出的最大范围
  • 如果我们把nice值设置为-10

我们发现,进程的pri变为了70,但是我们刚才不是刚把进程的优先级调至为99吗?

  • 其实这是因为:pri(old),是指老的优先级,这个优先级永远是80! 所以再次调整时,还是从80开始变化。

  • 我们把nice值设置为极小: 

进程的pri果然为60,所以nice值的范围就是 [-20, 19] 。


可能你会有疑问,为什么要给进程优先级加上限制范围呢? 

  • 如果不加限制,把自己的优先级调整的非常高,别人的优先级非常低,又因为OS是根据进程的pri来执行先后顺序的,这样做可能就会打乱操作系统执行顺序。
  •   这样常规进程就很难分配到资源,是不是有点 “兴,百姓苦,亡,百姓苦” 的感觉了,其实这就是一种 进程饥饿 的问题。

为了尽量避免进程饥饿的问题,现在的任何分时操作系统,都是较为公平的进行调度。 

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐