Linux2.6进程调度分析(3)-与调度有关的函数分析

来源:互联网 发布:laravel nginx 403 编辑:程序博客网 时间:2024/05/22 13:01

前面两篇文章从原理角度分析了进程的调度,本文将从具体的源码出发,分析与进程进程调度密切相关的几个函数。

1.时间片的分配:task_timeslice()

正如我们所知的那样,进程的时间片与进程的静态优先级有直接的关系。从代码中可以看到,根据进程静态优先级static_prio与NICE_TO_PRIO(0)的大小关系,进程时间片的分配可以分为两条路线。以下代码如无特别说明均位于linux/kernel/sched.c下。

1static unsigned int task_timeslice(task_t *p)
2{
3    if (p->static_prio < NICE_TO_PRIO(0))         return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio);
4    else
5        return SCALE_PRIO(DEF_TIMESLICE, p->static_prio);
6}

NICE_TO_PRIO以及PRIO_TO_NICE宏的作用将进行nice值和进程静态优先级之间的转换。nice也用来表示进程的静态优先级,只不过它与静态优先级的大小范围不同,因此可以将nice看作是static_prio的缩影。

1#define MAX_USER_RT_PRIO        100
2#define MAX_RT_PRIO             MAX_USER_RT_PRIO
3#define NICE_TO_PRIO(nice)  (MAX_RT_PRIO + (nice) + 20)
4#define PRIO_TO_NICE(prio)  ((prio) - MAX_RT_PRIO - 20)

目前我们已经知道普通进程的静态优先级大小范围是100到139,因此从上面的一些列宏可以得知,nice的取值范围为-20到19。

因此,NICE_TO_PRIO(0)取值为120,也就是说进程时间片分配的两条路线是根据静态优先级120进行划分的。从SCALE_PRIO宏的定义我们可以看到,该宏的作用是取两个数值(具体应该是时间片)的最大者。

1#define MAX_PRIO                (MAX_RT_PRIO + 40)
2#define USER_PRIO(p)        ((p)-MAX_RT_PRIO)
3#define MAX_USER_PRIO       (USER_PRIO(MAX_PRIO))
4#define DEF_TIMESLICE       (100 * HZ / 1000)
5#define MIN_TIMESLICE           max(5 * HZ / 1000, 1)
6# define HZ             1000  //位于linux/include/asm-i386/param.h
7#define SCALE_PRIO(x, prio) /
8max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE)

从上面的宏定义可知,(MAX_USER_PRIO/2)为20。当进程静态优先级小于120时,x的值为DEF_TIMESLICE*4,具体即为400ms;否则x为100ms。因此对于SCALE_PRIO宏可以用下面的公式来表达:

静态优先级<120,基本时间片=max((140-静态优先级)*20, MIN_TIMESLICE)

静态优先级>=120,基本时间片=max((140-静态优先级)*5, MIN_TIMESLICE)

其中MIN_TIMESLICE为系统所规定的最小时间片大小。

2.对可运行队列的操作

在优先级数组结构prio_array中,数组queue用来表示每个优先级所形成的可运行进程队列,而且过期进程和活动进程分别对应这样一个数组。