深入Linux内核架构-进程管理和调度(九)

一、处理优先级

内核内部对优先级的处理相当复杂。

1、优先级的内核表示

在用户空间可以通过nice命令设置进程的静态优先级,这在内部会调用nice系统调用。进程的nice值在-20和+19之间(包含)。值越低,表明优先级越高。

内核使用一个简单些的数值范围,从0到139(包含),用来表示内部优先级。同样是值越低,优先级越高。从0到99的范围专供实时进程使用。nice值[-20, +19]映射到范围100到139,如图2-14所示。实时进程的优先级总是比普通进程更高

下列宏用于在各种不同表示形式之间转换( MAX_RT_PRIO指定实时进程的最大优先级,而MAX_PRIO则是普通进程的最大优先级数值):

linux/sched.h

kernel/sched.c

2、计算优先级

只考虑进程的静态优先级是不够的,还必须考虑下面3个优先级。即动态优先级( task_struct->prio)、普通优先级

( task_struct->normal_prio)和静态优先级( task_struct->static_prio)。这些优先级按有趣的方式彼此关联,下文中会具体讨论。

static_prio是计算的起点。假定它已经设置好,而内核现在想要计算其他优先级。一行代码即可:

p->prio = effective_prio(p);

辅助函数effective_prio执行了下列操作:
kernel/sched.c

首先计算了普通优先级,并保存在normal_priority。这个副效应使得能够用一个函数调用设置两个优先级( prio和normal_prio)。另一个辅助函数rt_prio,会检测普通优先级是否在实时范围中,即是否小于MAX_RT_PRIO。请注意,该检测与调度类无关,它只涉及优先级的数值。

假定在处理普通进程,不涉及实时调度。在这种情况下, normal_prio只是返回静态优先级。结果很简单:所有3个优先级都是同一个值,即静态优先级。

实时进程的情况有所不同。注意普通优先级的计算方法:

kernel/sched.c

普通优先级需要根据普通进程和实时进程进行不同的计算。__normal_prio的计算只适用于普通进程。而实时进程的普通优先级计算,则需要根据其rt_priority设置。由于更高的rt_priority值表示更高的实时优先级,内核内部优先级的表示刚好相反,越低的值表示的优先级越高。因此,实时进程在内核内部的优先级数值,正确的算法是MAX_RT_PRIO - 1 - p->rt_priority。这一次请注意,与effective_prio相比,实时进程的检测不再基于优先级数值,而是通过task_struct中设置的调度策略来检测。

__normal_priority函数只是返回静态优先级:

但还有一个问题:为什么内核在effective_prio中检测实时进程是基于优先级数值,而非task_has_rt_policy?对于临时提高至实时优先级的非实时进程来说,这是必要的,这种情况可能发生在使用实时互斥量( RT-Mutex)时。
 

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值