进程调度
linux调度策略:SCHED_OTHER/SCHED_FIFO/SCHED_RR
linux支持如下3种调度策略:
- SCHED_OTHER:分时调度策略,非实时即普通进程
- SCHED_FIFO:实时调度策略(先进先出),SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。
- SCHED_RR: 实时调度策略(时间片轮转),SHCED_RR策略的进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。
如何设置线程调度策略
在create线程后,可以通过pthread_setschedparam接口设置线程调度策略和调度优先级。
SCHED_OTHER是不支持设置优先级的(SCHED_OTHER策略的sched_priority必须设置为0),FIFO和SCHED_RR支持优先级的设置,范围是1-99(值越小优先级越高)。
静态、动态、实时优先级、时间片计算与nice值
如下参考深入理解liunx内核第三版->第7章进程调度
每个进程的进程描述符都包含以下字段(第7章进程调度->表7-5 与调度相关的进程描述符):
int prio 进程的动态优先级
int static_prio 进程的静态优先级
int rt_priority 进程的实时优先级
静态优先级:
静态优先级范围是[100,139]。默认进程的静态优先级是120(对应的nice值是0)。
nice值:
nice值可以理解为静态优先级的另一种表达方式。nice的范围是[-20,19],-20对应的静态优先级是100,19对应的静态优先级是139。所以也可用nice值表示静态优先级。调整静态优先级都是通过调整nice值。
静态优先级决定了进程的基本时间片,静态优先级和基本时间片的关系如下:
动态优先级:
范围也是[100,139]。动态优先级是会在进程运行过程中动态变化的(bonus值是动态变化的)。动态优先级是决定普通进程的调度优先级,动态优先级不影响实时进程的调度。动态优先级由静态优先级和bonus值决定的。
bonus是范围0-10的值。值小于5表示降低进程动态优先级对进程进行惩罚,大于5表示增加进程动态优先级对进程进行奖励。bonus值取决于进程的平均睡眠时间。进程睡眠时间越长,bonus值越大。
实时优先级:范围[1,99]。实时优先级决定实时进程的调度优先级。
tips:
- 实时进程有两种策略,FIFO和RR。FIFO实时进程并不是基于时间片调度的,所以FIFO实时进程并没有时间片的概念。FIFO实时进程优先级最高的进程会一直占有CPU,直到更高优先级FIFO实时进程抢占CPU或者自己进入休眠。
- 修改nice值可以改变进程的静态优先级。对于普通进程,nice值影响时间片的长度和动态优先级。对于RR实时进程,nice值只影响时间片,不影响实时优先级。
- 如上图所示,当系统中存在普通进程和实时进程时,用于表示实时进程的实时优先级范围是1-99,普通进程的动态优先级范围是100-139,是不是实时进程的实时优先级和普通进程的动态优先级是一个概念,调度程序可根据[1,139]来区分所有进程的优先级
进程调度总结
系统中的每个进程都关联了一个调度策略和优先级,调度器正是根据调度策略和优先级进行线程调度的,从而决定哪个线程将在下一个调度中得到CPU时间;
进程根据调度策略分为实时进程(SCHED_FIFO, SCHED_RR)和普通进程(SCHED_OTHER, SCHED_IDLE, SCHED_BATCH)。
实时进程实时优先级范围1-99,越小优先级越高。实时进程任何时候都优先于普通进程运行。
普通进程实时优先级为0,普通进程之间的调度可用动态优先级确定。动态优先级由静态优先级和bonus值决定。bonus值取决于进程的平均睡眠时间,是系统动态调整的。静态优先级在进程创建是设定,进程运行过程中可以人为的调整nice值调整静态优先级(静态优先级系统不会动态调整)。
调度器为每个优先级维护了一个待调度线程的列表,当需要进行调度时,调度器访问最高优先级的非空的列表,然后从列表头选择一个线程调度运行;线程的调度策略决定了一个可调度线程应该放在哪个列表的哪个位置。