Linux

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > Linux > Linux进程优先级&&进程切换

Linux进程的优先级&&进程切换方式

作者:清源妙木真菌

本文概述进程优先级与调度算法,涵盖优先级调整方法(nice、renice命令)及Linux 2.6 O(1)调度器,通过运行队列、task_struct结构和位图优化进程调度效率

前言

本文主要介绍了进程的优先级及其调度算法:

一、进程优先级

我们计算机里面一般只有一个cpu用来处理进程数据,所以对于进程获得CPU的使用权需要一种重要调度指标,而进程优先级就是这种指标,它用来决定一个进程能够优先获得CPU时间、内存等系统资源。

1.1 基本概念

1.2 查看系统进程

在linux或者unix系统中,⽤ps ‒l 命令则会类似输出以下⼏个内容:

我们很容易注意到其中的⼏个重要信息,有下:

1.3 PRI和NI

PRI也还是⽐较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执⾏的先后顺序,此值越⼩进程的优先级别越⾼

那NI呢?就是我们所要说的nice值了,其表⽰进程可被执⾏的优先级的修正数值

PRI值越⼩越快被执⾏,那么加⼊nice值后,将会使得PRI变为:PRI(new)=PRI(oldest)+nice(这意味着我们修改进程优先级的时候,无论中间的PRI怎么改变,都会会以最开始的PRI值作为基准值去改变)

这样,当nice值为负值的时候,那么该程序将会优先级值将变⼩,即其优先级会变⾼,则其越快被执⾏

所以,调整进程优先级,在Linux下,就是调整进程nice值

nice其取值范围是-20⾄19,⼀共40个级别。(当我们调整的nice值超过这个区间的时候,会以区间里面的最低或最高值作为nice值)

需要强调⼀点的是,进程的nice值不是进程的优先级,他们不是⼀个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正数据

1.4 调整优先级

虽然一般情况下我们是不需要调整优先级的,不过我们仍然需要了解如何调整优先级。

使用下面的命令都需要管理者的身份。

1.4.1 top命令

top命令更改已存在进程的nice:

1.4.2 nice命令

nice命令用于在启动一个新进程时指定其优先级,即进程的“nice值”。Nice值是一个整数,范围从-20(最高优先级)到19(最低优先级),默认情况下,大多数进程的nice值为0。

语法:

参数:

1.4.3 renice命令

renice命令用于修改已经运行的进程的优先级。

语法:

选项:

二、进程切换

2.1 补充概念

竞争性:系 统进程数⽬众多,⽽CPU资源只有少量,甚⾄1个,所以进程之间是具有竞争属性的。为了⾼效完成任务,更合理竞争相关资源,便具有了优先级

独⽴性: 多进程运⾏,需要独享各种资源,多进程运⾏期间互不⼲扰

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

并发: 多个进程在⼀个CPU下采⽤进程切换的⽅式,在⼀段时间之内,让多个进程都得以推进,称之为并发

2.2 进程的运行和切换步骤(重要)

在进程运行的过程中会有个时间片的概念,是操作系统进行进程调度时分配给每个进程的一段固定时间。这么做一部分上是为了防止某个进程卡死的情况,例如某个进程调度的时候代码内部有个while(1)函数导致一直运行。及时的切换到运行队列里其它进程是很有必要的

时间片内,进程可以执行其代码、访问内存和进行输入输出操作。当进程的时间片用完时,操作系统会暂停该进程的执行,并将其保存到某种状态(通常是通过进程控制块PCB),然后切换到另一个进程的时间片。

切换步骤:

二、Linux2.6内核进程O(1)调度队列(重要)

操作系统是如何根据优先级来开展的调度呢? 

一个cpu一个运行队列

其中queue的类型为struct task_struct队列中的[0-99]为实时优先级我们不做考虑,而[100-139]则是我们进程的优先级序列。

2.1 基本过程

在Linux2.6内核中,每个CPU都拥有一个独立的运行队列(run_queue)。

运行队列用于管理和调度该CPU上的所有可运行进程。

task_struct结构体:

这是一个类似哈希链地址法的指针数组,遍历这个指针数组从上到下,从左到右就完成了对进程的优先级的调度!!!

除此之外我们在running下设计了个waiting,这么做的目的是

当我们遍历这个指针数组的时候,可能会有新的task_struct插入进来,或者一个进程时间片结束后进程还没被cpu处理完,那么此时就会进入到waiting里面,当running这个指针数组遍历完的时候,利用位图(bitmap)判断指针数据这个队列是否为空,然后只需要交换上面图片中的run和wait两者指向指针的地址,就能继续调度未处理完数据或者新的task_struct了!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文