系统中存在很多进程,它们由进程调度组件调度交替运行,多个进程共享CPU时间,每个进程使用CPU时间的一部分(时间片),由于时间很快,造成了并行执行的错觉。
- 两种调度器 -管理调度流程
- 直接调度器: 用于进程睡眠或主动让出CPU资源
- 周期调度器:使用定时器,以指定频率运行,周期性的检测是否需要进行进程调度
- 调度类- 负责进程调度底层算法支持
- 完全公平调度类(CFS):Linux 中主要使用的调度类
- 实时调度类: 用于支持POSIX标准的实时进程
- 调度器和调度类之间的关系
调度器周期性调用当前进程调度器类,选择将要运行的进程,并更新统计信息及切换调度。
- 进程优先级
优先级用于进程调度算法,它影响一个进程是否有更多的机会被调度,进程优先级通过nice系统调用设定,其值范围为 -20到+19间,值越低表示优先级越高。
内核提供优先级辅助宏,可以在nice和prio之前转换
#define MAX_NICE 19
#define MIN_NICE -20
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
* tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
* values are inverted: lower p->prio value means higher priority.
*/
#define MAX_RT_PRIO 100
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
* to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
* and back.
*/
#define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO)
#define PRIO_TO_NICE(prio) ((prio) - DEFAULT_PRIO)
计算进程优先级,进程有3个优先级,静态优先级(static_prio)、普通优先级(normal_prio)、动态优先级(prio),静态优先级是进程优先级计算的基础,系统中有 普通进程、实时进程、空闲进程,它们之间的优先级为 实时进程》普通进程》空闲进程
int prio;
int static_prio;
int normal_prio;
内核计算优先级函数
static int effective_prio(struct task_struct *p)
{
//计算进程普通优先级
/*
实时进程: MAX_RT_PRIO-rt_priorit
普通进程: 默认返回static_prio
空闲进程: MAX_DL_PRIO-1
*/
p->normal_prio = normal_prio(p);
/*
如果进程优先级在实时进程优先级范围内,则保持优先级不变
*/
if (!rt_prio(p->prio))
return p->normal_prio;
return p->prio;
}
- 负荷权重
优先级只是影响进程重要性的一个方面,进程的负荷权重也是影响进程重要性的一个指标,它根据进程的静态优先级计算。
进程通过调整nice值来增加或减少获取的CPU时间,内核通过一个转换表将优先级转换为权重
const int sched_prio_to_weight[40] = {
/* -20 */ 88761, 71755, 56483, 46273, 36291,
/* -15 */ 29154, 23254, 18705, 14949, 11916,
/* -10 */ 9548, 7620, 6100, 4904, 3906,
/* -5 */ 3121, 2501, 1991, 1586, 1277,
/* 0 */ 1024, 820, 655, 526, 423,
/* 5 */ 335, 272, 215, 172, 137,
/* 10 */ 110, 87, 70, 56, 45,
/* 15 */ 36, 29, 23, 18, 15,
};
可以看到每个数组元素之间的乘数因子为1.25,如nice=0的进程 A和B,得到的CPU时间为各50% ,1024/(1024+1024)=0.5,假如我们调整进程A的nice=1 ,此时进程权重为820,那么A进程获得的CPU时间为 820/(1024+820)=0.45(约等于),那么A进程CPU时间为45%,B进程为6=55% 1024/(1024+820)。
后续涉及就绪队列、抢占、SMP等 未完待续。。。