linux 的调度策略与优先级

linux 的调度策略与优先级

参考资料如下:

  1. man手册man 7 sched
  2. 内核文档 Documentation/scheduler。

首先需要说明,我们常说的进程调度器是传统的说法,但是实际上进程是资源管理的单位,线程才是调度的单位.有时也会说任务调度等。

linux的调度机制由调度策略(policies)优先级(priority)两个属性共同决定.其中调度策略又可以分为实时调度策略通用调度策略(非实时)。其中通用调度策略的优先级值为0.而实时调度策略的优先级取值范围为1~99.可以看出,实时调度策略的优先级总是大于通用调度策略。而优先级高线程的总是会被调度器优先调用。其中实时调度策略包含SCHED_RR,SCHED_FIFO调度策略。通用调度策略包含SCHED_OTHERSCHED_IDLESCHED_BATCH调度策略。即如下关系:
linux的调度机制由调度策略(policies)优先级(priority)共同决定:

  1. 优先级:确定哪个线程被优先调度。实时调度策略的优先级总是大于通用调度策略。
  2. 调度策略(policies)分如下几种:
    1. 实时调度策略:spriority值的取值范围为0~99.当线程间的优先级不同时,按照优先级高的先调度原则。当优先级相同时,分为如下两种方式:
      1. SCHED_RR:优先级相同的线程按固定的时间片循环调度。下面会详细讲解。
      2. SCHED_FIFO:与SCHED_RR相似,优先级相同的线程也是循环调度。不过没有时间片的概念。下面会详细讲解。
    2. 通用调度策略(非实时):spriority值为0.
      1. SCHED_OTHER:
      2. SCHED_IDLE:
      3. SCHED_BATCH:

所有的调度策略最后通过链表的方式组合成一个调度类。由linux内核调度。

各种调度策略介绍

  1. 实时调度策略之SCHED_RR:Round-robin scheduling
    1. 当线程间的优先级不同时,优先级高的先调度。当优先级相同时,固定的时间片循环调度。被调用的线程满足如下条件时会让出CPU:
      1. 调度期间的时间片使用完了。
      2. 自动放弃CPU。如调用了阻塞相关的接口函数或调用了sched_yield()。
      3. 被一个优先级更高的线程抢占了
      4. 线程终止了。
    2. 如果因为时间片使用完了或自愿放弃CPU而导致线程让出CPU,此时此线程将会被放置在与其优 先级级别对应的队列的队尾。如果因为被抢占而让出CPU,则会放置到队头,等更高优先级让出cpu时,继续执行此线程。
  2. 实时调度策略之SCHED_FIFO:First in-first out scheduling
    1. SCHED_RR实时调度策略相似,不过它没有时间片的概念。被调用的线程让出CPU条件与SCHED_RR类似,只是没有时间片使用完的情况.
  3. 通用调度策略之SCHED_OTHER:time-sharing scheduling
    1. 分时循环调度策略。也就是我们常说的CFS(Completely Fair Scheduler)完全公平调度器。是系统的默认调度策略。按动态时间片循环调度。动态时间片nice属性值决定。每个SCHED_OTHER策略的线程都拥有一个nice值,其取值范围为−20~19,默认值为0.nice值是一个权重因子,值越小,权重越大。CPU为其分配的动态时间片会越多。
  4. 通用调度策略之SCHED_BATCH
    1. 此策略会让频繁被唤醒的线程在调度时次数会变少。其他与SCHED_OTHER策略类似。
  5. 通用调度策略之SCHED_IDLE
    1. 可以理解为nice=19的SCHED_OTHER策略。当系统中没有其他线程需要使用CPU时才会大量使用CPU。
  6. 调度策略之SCHED_DEADLINE
    1. 自从3.14版本以来,Linux提供了一个截止日期调度策略(SCHED_DEADLINE)。

调度相关的用户空间接口

修改nice值相关的函数接口:

  1. int nice(int inc)
    1. 所属头文件:<unistd.h>
    2. 描述:修改当前进程的nice值。此函数已经被更通用的setpriority()取代。
    3. inc:在当前nice的基础上加inc.
    4. return: 如果成功,返回新设置的nice值。
    5. eg:nice(3)、nice(-5)
  2. int setpriority(int which, int who, int prio)
    1. 描述: 设置通用进程的nice值。这里的priority不要与上边讲到的优先级混淆。
    2. which:决定who传入的参数含义,which可选值:
      1. PRIO_PROCESS:表明who为进程id.如果等于零,则为当前进程
      2. PRIO_PGRP:表明who为进程组id.如果等于零,则为当前进程组
      3. PRIO_USER:表明who为用户(real user)id.如果等于零,则为当前用户
    3. prio:-20~19之间的nice值。
    4. return: 成功返回0。失败返回-1.。
  3. int getpriority(int which, int who)
    1. 所属头文件:<sys/time.h>,<sys/resource.h>
    2. 描述:获取进程的nice值。
    3. return: 返回进程调度优先级(-20~19)。
    4. eg: getpriority(PRIO_PROCESS, getpid());

修改优先级与调度策略相关的函数接口:

  1. int sched_get_priority_max(int policy)
    1. 描述: 查看调度策略最大优先级。
    2. policy 可指定的值如下:
      1. SCHED_OTHER
      2. SCHED_BATCH
      3. SCHED_IDLE
      4. SCHED_FIFO
      5. SCHED_RR
    3. return: 成功返回最大优先级值。失败返回-1.
  2. int sched_get_priority_min(int policy)
    1. 查看调度策略最小优先级。其他同sched_get_priority_max().
  3. int sched_setscheduler(pid_t pid, int policy,const struct sched_param *param)
    1. 描述: 设置进程的调度策略和优先级。
    2. policy 可指定的值如下:
      1. SCHED_OTHER
      2. SCHED_BATCH
      3. SCHED_IDLE 对于这三种策略,param->sched_priority的值必须为0.
      4. SCHED_FIFO
      5. SCHED_RR 对于这两种策略,需要指定param->sched_priority的值。
    3. param:指定调度策略的优先级。struct sched_param的结构体如下:
      struct sched_param {
          int sched_priority; //优先级1~99
      };
      
    4. return: 成功返回0。失败返回-1.
  4. int sched_getscheduler(pid_t pid)
    1. 所属头文件:<sched.h>
    2. 描述: 获取进程的调度策略。
    3. pid 进程id.如果为0,表示为本线程。
    4. return: 成功返回调度策略值(非负整数)。失败返回-1.
      1. SCHED_OTHER 0
      2. SCHED_FIFO 1
      3. SCHED_RR 2
      4. SCHED_BATCH 3
      5. SCHED_IDLE 5
  5. int sched_setparam(pid_t pid, const struct sched_param *param)
    1. 描述: 设置进程的优先级。sched_setscheduler()函数的子集。
    2. param:见sched_setscheduler()函数中的描述。
    3. return: 成功返回0。失败返回-1.
  6. int sched_getparam(pid_t pid, struct sched_param *param)
    1. 描述: 获取进程的优先级。
    2. param:见sched_setscheduler()函数中的描述。用于接收要获取的优先级值。
    3. return: 成功返回0。失败返回-1.

linux特有的函数接口,可用于修改上边提到的所有属性:

  1. int sched_setattr(pid_t pid, struct sched_attr *attr,unsigned int flags)
    1. 描述: 设置进程的调度策略。
    2. struct sched_attr结构体如下:
      struct sched_attr {
             u32 size;              //结构体大小
             u32 sched_policy;      //调度策略
             u64 sched_flags;       //可选属性:SCHED_FLAG_RESET_ON_FORK 表示子进程创建时不继承此策略。
             s32 sched_nice;        //通用调度策略的nice值
             u32 sched_priority;    //优先级
             /* Remaining fields are for SCHED_DEADLINE */
             u64 sched_runtime;
             u64 sched_deadline;
             u64 sched_period;
         };
      
    3. flags 目前为0.
    4. return: 成功返回0。
  2. int sched_getattr(pid_t pid, struct sched_attr *attr,unsigned int size, unsigned int flags)
    1. 描述: 获取进程的调度策略。
    2. size: attr结构体的大小。
    3. 其他参数同sched_setattr().

其他接口:

  1. int sched_yield(void)
    1. 描述:进程主动放弃cpu.
  2. int sched_rr_get_interval(pid_t pid, struct timespec *tp)
    1. 获取SCHED_RR调度策略的进程在每次使用CPU时分配到时间片的长度。
    2. tp:获取到的时间长度。
    3. 成功返回0,失败返回-1.

线程相关的调度设置函数:相关线程属性设置。


关于技术交流

此处后的文字已经和题目内容无关,可以不看。
qq群:825695030
微信公众号:嵌入式的日常
如果上面的文章对你有用,欢迎打赏、点赞、评论。二维码

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

theboynoName

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值