前言:
进程优先级是操作系统中的一个关键概念,它直接影响到进程的调度顺序和执行权。了解进程优先级对于优化和提升系统性能至关重要。让我们直接进入今天的主题!
?优先级相关✈️什么是优先级 在日常生活中,我们常常遇到需要排队的情况,比如在公路上等红灯,在医院挂号,或者在食堂吃饭。然而,救护车可以无视红灯,急诊病人可以优先挂号,食堂里的老师可以插队...
这些需要排队的事物可以被视为进程,而像救护车、急诊病人以及食堂的老师等,则是具有优先权的象征。优先权的存在是为了处理更重要的事情。
因此,优先级的概念清晰可见:进程通过某种方式(排队)来确定访问资源的先后顺序。
细心的你可能已经注意到,优先级似乎与我们之前学习的权限概念相似。实际上,优先级和权限是有区别的:权限决定的是能不能的问题,而优先级决定的是先后顺序的问题。
✈️为什么要有优先级 如果食堂的窗口数量远超人数,如果自习室的座位非常多而人却很少,我们就不需要排队。也就是说,当资源充足时,排队是不必要的。
因此,优先级产生的本质是因为资源相对稀缺。
✈️进程的优先级 为了更直观地展示优先级,我们可以运行以下代码:
代码语言:javascript代码运行次数:0运行复制```javascript
include#include#includeint main(){while(1){printf("this is a process, pid=%d\n", getpid());sleep(1);}return 0;}
将此程序运行起来变成进程,然后使用以下命令查看进程属性:代码语言:javascript代码运行次数:0运行复制
javascript ps -la#显示当前用户的所有进程
我们可以看到,横着的蓝色框是我们启动的进程,竖着的蓝色框有一栏叫做 PRI 的数值,PRI 就是 priority,优先权的意思。
竖着的蓝色框显示的是优先级,而优先级是数值,所以它一定是 task_struct 结构体中的一个属性:
代码语言:javascript代码运行次数:0运行复制javascript struct task_struct{int PRI;//优先级//...}
运行我们编写的程序,查询该进程的权限为80,这表明 Linux 下的进程优先级本质上是数字。实际上,Linux 下的优先级是可以修改的,修改范围为 [60, 99],且进程的默认优先级值是80。而优先级数字越小,表示该进程的优先级越高!
?调整进程优先级✈️调整优先级 我们已经了解了进程优先级的概念和原因,接下来看看如何操作?
运行上面的程序,打印出进程的pid,然后使用 top 命令进入 Linux 任务管理器:
代码语言:javascript代码运行次数:0运行复制```javascript
top#进入任务管理器
进入任务管理器后,输入 'r',进入修改进程权限的操作,然后输入进程标识符:
接着会出现文字提示:
然后输入要修改的值,例如,这里我输入10:
此时再使用 ps 查看,会发现进程的 PRI 这一项变为了90,但不仅仅是 PRI 这一栏变了,还有一栏叫做 NI 的值也变了,而且正好是我们输入的数值!
实际上,Linux 系统支持用户调整优先级,但并不是让用户直接修改 pri 值,而是修改 nice 值。nice 值不是优先级,而是优先级的修正数据。
所以真正的优先级应该是:pri = pri(old) + nice;(old 指老的优先级)
因此,我们刚刚修改的并不是优先级,而是 nice 值。
✈️优先级极限测试 但事实果真如此吗?进程的优先级真的只能在 [60,99] 这个范围内移动吗?如果不相信,我们可以进行极值测试:
我们将程序的进程值调到尽可能大:

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

我们发现,进程的 pri 变为了70,但我们刚才不是刚把进程的优先级调至99吗?
实际上这是因为:pri(old),是指老的优先级,这个优先级永远是80!所以再次调整时,还是从80开始变化。
我们把 nice 值设置为极小值:

进程的 pri 果然为60,所以 nice 值的范围就是 [-20, 19]。
你可能会有疑问,为什么要给进程优先级加上限制范围呢?
为了尽量避免进程饥饿的问题,现在的任何分时操作系统,都是较为公平地进行调度。
?Linux的调度与切换 Linux 调度切换是学习 Linux 系统编程的重要知识,我们提前了解一下:
我们之前提到过,CPU 不会把一个进程全部执行完才切换到下一个进程,而是基于时间片进行轮转执行的。关于进程的调度与切换,有以下几个相关特性:
竞争性:系统进程数量众多,而 CPU 资源只有少量,甚至只有1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理地竞争相关资源,便有了优先级。如前所述,为了避免竞争饥饿问题,操作系统会合理地给进程分配各种资源。
独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰。进程的独立性是学习 Linux 系统编程特别重要的一个知识,多个进程在系统里同时运行,但它们互不干扰,一个进程挂了不会影响其他进程,就算是父子进程也是如此。
并行:多个进程在多个 CPU 下分别同时运行,称为并行。如果一台电脑有多个 CPU,并且每个 CPU 下有对应数量的进程分别同时运行,那么就称之为并行。
并发:多个进程在一个 CPU 下采用进程切换的方式,在一段时间之内让多个进程都得以推进,称为并发。并发与并行不同,我们大部分人的电脑其实只有一个 CPU,而进程通常会有多个。为了考虑资源分配等问题,每个进程都有自己的时间片,时间片用完就切换到下一个进程,自己则重新排队,等待再次调度。虽然每次 CPU 执行任务只执行很少的时间片,但对于我们人类来说并看不出来进程是在不断切换的。多个进程在一个 CPU 下采用进程切换的方式,一段时间内让多个进程都能推进任务,称之为并发。
?✏️总结 在操作系统中,资源总是少数,所以进程需要使用排队的方式来获取资源,而有些重要的进程优先级较高,可以插队。进程的优先级是可调整的,调整范围为:[60, 99],实际上我们调整的是进程的 nice 值,nice 值的范围是 [-20, 19]。进程的调度和切换是操作系统中重要的概念,其中竞争、独立、并发、并行这些概念比较常见。如果这篇文章对你有帮助的话,还望留下一个小小的赞呀~~










