您的位置:首页 > 运维架构 > Linux

linux进程调度 - 优先级处理

2013-07-31 10:01 295 查看
从用户的角度来看,优先级非常简单,不过是从-20 ~ 19之间的数字。但是内核内部对这些优先级的处理相当的复杂。

优先级内核表示

在用户空间可以通过系统调用nice更改当前进程的优先级,对于linux系统来说优先级的表示范围是-20~19,值越小表示进程的优先级越高。至于说为什么选择这么一个诡异的范围,真相已经淹没在历史中了。

在内核中使用一个看起来正常得多的表示方法,从0到139。值越小,优先级越低。其中0~99是给实时进程使用的,nice值的-20~19正好可以映射到100到139这个范围内,这也意味着nice只能设置非实时进程的优先级。实时进程的优先级一定比普通进程的优先级高。

计算优先级

上面说的都是进程的静态优先级,有时我们还需要考虑下面三种优先级:

进程的动态优先级task_struct->prio, 普通优先级task_struct->normal_prio,和静态优先级task_struct->static_prio。

动态优先级和普通优先级是通过静态优先级计算出来的:

p->prio = effective_prio(p);

辅助函数effective_prio执行了下列操作:

/*
 * Calculate the current priority, i.e. the priority
 * taken into account by the scheduler. This value might
 * be boosted by RT tasks, or might be boosted by
 * interactivity modifiers. Will be RT if the task got
 * RT-boosted. If not then it returns p->normal_prio.
 */
static int effective_prio(struct task_struct *p)
{
        p->normal_prio = normal_prio(p);
        /*
         * If we are RT tasks or we were boosted to RT priority,
         * keep the priority unchanged. Otherwise, update priority
         * to the normal priority:
         */
        if (!rt_prio(p->prio))
                return p->normal_prio;
        return p->prio;
}


这个函数返回动态优先级,同时在函数内部会修改进程的普通优先级。

对于普通进程,我们可以看出static_prio,normal_prio和prio是完全相同的。实时进程的优先级计算方法是不同的,要根据rt_priority计算,由于更高的priority表示更高的优先级,内核内部的优先级表示则完全相反,越低的值表示的优先级越高。

normal_prio非常简单,仅仅返回了p->static_prio,之所以使用一个函数封装这个简单的功能,是因为历史的原因,在原来的O(1)调度器时,普通优先级的计算涉及到很多复杂的技巧性工作。

计算负载权重

优先级固然重要,但是在进程调度时考虑到task-struct->se.load中保存的负荷权重。

函数set_load_weight负责根据进程类型及其静态优先级计算负荷权重。

对于普通进程,内核维护了一个表,从-20~19每个优先级对应表中一项

static const int 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, 共有40项,prio_to_weight[0]对应着优先级100,prio_to_wright[39]对应着优先级139。而是是进程的负载则是prio_to_weight[0]的2倍。其实我们完全没必要记住这些奇怪的数字,只要知道实时进程权重更大即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: