Linux内核调度策略

linux内核的三种调度方法:

1,SCHED_OTHER 分时调度策略,
2,SCHED_FIFO实时调度策略,先到先服务 
3,SCHED_RR(Round-Robin)实时调度策略,时间片轮转

  • 实时进程将得到优先调用,实时进程根据实时优先级决定调度权值
  • 分时进程则通过nice和counter值决定权值,nice越小,counter越大,被调度的概率越大,也就是曾经使用了cpu最少的进程将会得到优先调度

SHCED_RR和SCHED_FIFO

SHCED_RR和SCHED_FIFO都是实时调度策略,支持优先级的使用,他们分别为1和99,数值越大优先级越高。设置和获取优先级通过以下两个函数

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
param.sched_priority = 51; //设置优先级

系统创建线程时,默认的线程是SCHED_OTHER。所以如果我们要改变线程的调度策略的话,可以通过下面的这个函数实现。

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

不同之处在于:

  • 当采用SHCED_RR策略的进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。
  • SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。

如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO时必须等待该进程主动放弃后才可以运行这个优先级相同的任务。而RR可以让每个任务都执行一段时间。

SHCED_RR和SCHED_FIFO相同点:
  RR和FIFO都只用于实时任务。
  创建时优先级大于0(1-99)。
  按照可抢占优先级调度算法进行。
  就绪态的实时任务立即抢占非实时任务。

SCHED_OTHER

所有任务都采用linux分时调度策略时。 SCHED_OTHER是不支持优先级使用的在内核中SCHED_OTHER用SCHED_NORMAL代表。

Linux内核调度策略_第1张图片

 

非实时调度是基于linux CFS(Completely Fair Scheduler),即完全公平调度器。本文主要介绍SCHED_OTHER,其是标准的round-robin分时调度策略。SCHED_OTHER是通过优先级(nice值)来分配cpu资源的。

nice值主要用来影响进程占用CPU时间的长短。

linux中,使用nice值表示进程、线程的优先级(nice值)。nice的值越大,进程的优先级就越低,获得CPU调用的机会越少,nice值越小,进程的优先级则越高,获得CPU调用的机会越多(nice字面意思是美好的、友好的,nice越大的线程其优先级越低,即对其他线程越友好)。nice的取值范围为-20到19。一个nice值为-20的进程优先级最高,nice值为19的进程优先级最低。

所有任务都采用linux分时调度策略时即nice时,采用以下方式设置任务时间片。

  • 创建任务指定采用分时调度策略,并指定优先级nice值(-20~19)。
  • 将根据每个任务的nice值确定在cpu上的执行时间(counter)。
  • 如果没有等待资源,则将该任务加入到就绪队列中。
  • 调度程序遍历就绪队列中的任务,通过对每个任务动态优先级的计算(counter+20-nice)结果,选择计算结果最大的一个去运行,当这 个时间片用完后(counter减至0)或者主动放弃cpu时,该任务将被放在就绪队列末尾(时间片用完)或等待队列(因等待资源而放弃cpu)中。
  • 此时调度程序重复上面计算过程,转到第4步。
  • 当调度程序发现所有就绪任务计算所得的权值都为不大于0时,重复第2步。

p->counter = (p->counter >> 1) + ((20 - p->nice) >> 2) +1)
由公式可以计算出,对于标准进程(p->nice 为0), 得到的初始counter为6,即进程获得的时间片为60ms。
最高优先级进程(nice为-19)的初始counter值为10,进程的时间片为100ms。
最低优先级进程(nice为20)的初始counter值为1,进程时间片为10ms。
 结论是最高优先级进程会获得最低优先级进程10倍的执行时间,普通优先级进程接近两倍的执行时间。当然,这是在进程不进行任何IO操作的时候的数据,在有IO操作的时候,进程会经常被迫睡眠来等待IO操作的完成,真正所占用的CPU时间是很难比较的。
我们可以看到每次重新计算counter的时候,新的counter值都要加上它本身剩余值的一半,这种奖励只适用于通过SCHED_YIELD主动放弃CPU的进程,只有它在重新计算的时候counter值没有用完,所以在计算后counter值会增大,但永远不可能超过20。

如何查看nice值

如何更改nice值

  • 改变一个已经存在的进程的nice值
    # renice -15 25858 ;( 把 pid 为25858 的nice 值 改为 -15 )
    这时 PRI 的值 为 PRI(new)= PRI(old)+ (-15)
    PRI 的值越小 进程的 优先级越高

  • 以某个nice值运行进程
    # nice -n -15 process

-n ,--adjustment=N 两个参数含义相同,设置进程优先级的谦让值(修正值)为N

修正值的用法,进程真正的优先级=进程默认优先级+修正值(nice值)

你可能感兴趣的:(linux,运维,服务器)