浅析Linux下进程的调度策略与优先级

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析Linux下进程的调度策略与优先级相关的知识,希望对你有一定的参考价值。

参考技术A

在 Linux 中,线程是由进程来实现的,可以认为线程就是一个轻量级的进程,因此,线程调度是按照进程调度的方式来进行的。这样设计,线程调度流程可以直接复用进程调度流程,没必要再设计一个进程内的线程调度器了。

在 Linux 中,进程调度器是基于进程的调度策略与调度优先级来决定调度哪个进程运行。

调度策略主要包括:

调度优先级的范围是 0~99,数值越大,表示优先级越高。

其中,SCHED_OTHER、SCHED_IDLE、SCHED_BACH 为非实时调度策略,其调度优先级为 0。而 SCHED_FIFO、SCHED_RR 是实时调度策略,其调度优先级范围为 1~99。

实时调度策略的进程总是比非实时调度策略的进程优先级高。

在 Linux 内部实现中,调度器会为每个可能的调度优先级维护一个可运行的进程列表,以最高优先级列表头部的进程作为下一次调度的进程,所有的调度都是抢占式的,如果一个具有更高调度优先级的进程转换为可运行状态,那么当前运行的进程将被强制进入其等待的队列中。

SCHED_OTHER

该调度策略是默认的 Linux 分时调度策略,该调度策略为非实时的,其调度优先级总是为 0。

对于该调度策略类型的进程,调度器是基于动态优先级来调度的。动态优先级跟属性 nice 有关,nice 的值会随着进程的运行时间而动态改变,以确保所有具有 SCHED_OTHER 策略的进程公平地得到调度。

在 Linux 中,nice 的值范围为-20 ~ +19,默认值为 0。nice 值越大,则优先级越低,因此相对较低 nice 值的进程可以获得更多的处理器时间。

通过命令 ps -el 查看系统中的进程列表,其中 NI 列就是进程对应的 nice 值。

使用 top 命令,看到的 NI 列也是进程的 nice 值。

调整 nice 值,可以通过 shell 命令 nice ,该命令可以按照指定的 nice 值运行 cmd ,命令的帮助信息为:

重新调整已运行进程的 nice 值,可通过 renice 命令实现,命令的帮助信息为:

另外,可以执行 top 命令,输入 r ,根据提示输入进程的 pid ,再输入 nice 数值,也可以调整进程的 nice 值。

SCHED_FIFO

该调度策略为先入先出调度策略,简单概括,就是一旦进程占用了 CPU,则一直运行,直到有更高优先级的任务抢占,或者进程自己放弃占用 CPU。

SCHED_RR

该调度策略为时间片轮转调度策略,该调度策略是基于 SCHED_FIFO 策略的演进,其在每个进程上增加一个时间片限制,当时间片使用完成后,调度器将该进程置于队列的尾端,放在尾端保证了所有具有相同调度优先级的进程的调度公平。

使用 top 命令,如果 PR 列的值为 RT ,则说明该进程采用的是实时调度策略,其调度策略为 SCHED_FIFO 或者 SCHED_RR,而对于非实时调度策略的进程,该列的值为 NI + 20 。

可以通过命令 ps -eo state,uid,pid,ppid,rtprio,time,comm 来查看进程对应的实时优先级,实时优先级位于 RTPRIO 列下,如果进程对应的列显示为 - ,说明该进程不是实时进程。

chrt 命令可以用来很简单地更改进程的调度策略与调度优先级。在 Linux 下查看 chrt 命令的帮助信息:

比如,获取某个进程的调度策略,使用如下命令:

在比如,设置某个进程的调度策略为 SCHED_FIFO,调度优先级为 70,使用如下命令:

Linux 内核进程优先级与调度策略 ① ( SCHED_FIFO 调度策略 | SCHED_RR 调度策略 | 进程优先级 )



文章目录




一、Linux 内核调度策略



Linux 内核调度策略 :

  • SCHED_OTHER :分时调度策略 ;
  • SCHED_FIFO :实时调度策略 , 先到先服务 ; 进程 一旦 占有 CPU , 就一直运行 , 直到 有更高优先级的进程到达 时才放弃 CPU , 或者 进程自己放弃 CPU ;
  • SCHED_RR :实时调度策略 , 时间片轮转 ; 进程分配到 CPU 时间片用于执行 , 该时间片用完后 , 该进程 放到该优先级队列的末尾 , 等待系统重新分配时间片执行 ;


总结一下 , 就是 如果有 多个 相同优先级 的 " 实时进程 " ,

  • SCHED_FIFO策略需要 等待进程主动放弃 才可以执行其它优先级相同的任务 ,
  • SCHED_RR策略 每个 优先级相同的进程 , 都可以执行一个时间片 ;

特别注意 : 进程的优先级计算出的 调度权重 是可以修改的 , 由开发者确定 ;



参考 ​​【Linux 内核】调度器 ⑨ ( Linux 内核调度策略 | SCHED_NORMAL 策略 | SCHED_FIFO 策略 | SCHED_NORMAL 策略 | SCHED_BATCH策略 )​​ 博客 , 介绍了 Linux 内核相关的调度策略 ;



1、SCHED_FIFO 调度策略



​SCHED_FIFO​​ 是 " 实时进程调度策略 " , 这是一种 先进先出 ( First In First Out ) 调度策略 ;

该策略 不涉及 CPU 时间片机制 ( 分时复用机制 ) , 在没有高优先级进程的前提下 , 只能 等待其它进程主动释放 CPU 资源 ;

​SCHED_FIFO​​ 调度策略中 , 被 调度器 调度运行后的 进程 , 其运行时长不受限制 , 可以运行任意长的时间 ;



2、SCHED_RR 调度策略



​SCHED_RR​​ 是 " 实时进程调度策略 " , 使用的是 时间片轮 机制 , 对应的 时间值 在 运行时会 减少 ;

进程 使用完 CPU 时间片 后 , 会加入到 与 进程优先级 相应的 执行队列 的 末尾 ;

同时 , 释放 CPU 资源 , CPU 时间片会被轮给 相同进程优先级 的 其它进程 ;




二、进程优先级



实时进程 的 优先级 取值范围 1 1 1 ~ 99 99 99 , 其数值越大 , 优先级越高 ;

就绪状态 的 实时任务 , 可以 立刻抢占非实时任务 ;

如果 所有的 进程都采用 Linux 分时调度策略时 , 创建该进程时 , 必须 指定 优先级计算参数 ​​nice​​​ 值 , 取值范围 − 20 -20 −20 ~ 19 19 19 , 进程在 CPU 上的执行时间 是 结合 ​​​nice​​ 值计算出的 优先级权重 决定的 ;



在之前的博客

中 , 简单介绍了 进程优先级概念 , 本篇博客中开始介绍 Linux 内核中优先级相关源码 ;



进程优先级

限期进程

实时进程

普通进程

prio 调度优先级

等于 normal_prio 字段

等于 normal_prio 字段

等于 normal_prio 字段

static_prio 调度优先级

字段 值总为

0 0 0 , 没有意义

字段 值总为

0 0 0 , 没有意义

120 + n i c e \\rm 120 + nice 120+nice , 其数值越小 , 优先级越高

normal_prio 正常优先级


− 1 -1 −1

99 − r t _ p r i o r i t y 99 - \\rm rt\\_priority 99−rt_priority

120 + n i c e \\rm 120 + nice 120+nice , 其数值越小 , 优先级越高

rt_priority 实时优先级

字段 值总为

0 0 0 , 没有意义

字段 值为

1 1 1 ~ 99 99 99 , 其数值越大 , 优先级越高

字段 值总为

0 0 0 , 没有意义


以上是关于浅析Linux下进程的调度策略与优先级的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核进程优先级与调度策略 ① ( SCHED_FIFO 调度策略 | SCHED_RR 调度策略 | 进程优先级 )

Linux 内核进程优先级与调度策略 ② ( 获取调度策略对应的进程优先级函数 | sched_get_priority_max 函数 | sched_get_priority_min 函数 )

Android 进程管理篇(五)-调度策略与优先级

Linux 内核进程优先级与调度策略 ② ( 获取调度策略对应的进程优先级函数 | sched_get_priority_max 函数 | sched_get_priority_min 函数 )

Linux 操作系统原理 — 用户进程与内核线程的调度策略与切换开销

Linux 内核进程优先级与调度策略 ③ ( 设置获取线程优先级的核心函数 | 修改线程调度策略函数 )