今天查看了linux下的实时线程,FIFO和RR策略的调度,遇到一个问题:
priority越大优先级越高呢?还是越小越高呢?
回答这个问题要明白一个问题,首先,linux2.6内核将任务优先级进行了一个划分:
0——99 实时进程
100——139 非实时进程
现在,这个划分是起决定作用的,而且一定是数值越小,优先级越高。
但是,有时候从网上会看到 优先级数值越大,优先级越高?这又是怎么回事?难道有一种说法错了吗?
实际的原因是这样的,对于一个实时进程,他有两个参数来表明优先级——prio 和 rt_priority,prio才是调度所用的最终优先级数值,这个值越小,优先级越高;
而rt_priority 被称作实时进程优先级,他要经过转化——prio=MAX_RT_PRIO - 1- p->rt_priority;
MAX_RT_PRIO = 100;这样意味着rt_priority值越大,优先级越高;而内核提供的修改优先级的函数,是修改rt_priority的值,所以越大,优先级越高。
参考函数:
static inline int normal_prio(struct task_struct *p)
{
int prio;
if (task_has_rt_policy(p))
prio = MAX_RT_PRIO-1 - p->rt_priority;
else
prio = __normal_prio(p);
return prio;
}
============================================================================================================================================
1、linux调度器的一个接触特性是,它不需要时间片的概念,至少不需要传统的时间片
经典的调度器对系统中的进程风别计算时间片,使进程运行直至时间片用完。在所有的进程的时间片都用完时,则需要重新计算
当前的调度器只考虑进程的等待时间,即进程在就绪队列中已经等待了多长的时间
,对CPU时间需求最严格的的进程被调度执行
2、关于进程优先级:
task_struct采用了3个成员来表示进程的优先级:
prio、normal_prio表示动态优先级。
static_prio表示进程的静态优先级,静态优先级是进程启动时分配的优先级。
可以用nice和sched_setscheduler系统调用修改,否则在进程运行过程中一直保持恒定。
normal_priority表示基于进程的静态优先级和调度策略计算出的优先级。
所以,即使普通进程和实施进程具有相同的静态优先级,其普通优先级也是
不同的,进程分支时,子进程会继承普通优先级
但调度器考虑的优先级保存在prio。
由于在某些情况下内核需要暂时提高进程的优先级,因此需要第3个成员来表示。由于这些改变不是持久的,因此静态和普通优先级不受影响
rt_priority表示实时进程的优先级。该值不会代替前线讨论的那些值
最低的实时优先级为0,最高位99,值越小表示优先级越高,这里使用的管理不同于nice
/*
* 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.
*
* The MAX_USER_RT_PRIO value allows the actual maximum
* RT priority to be separate from the value exported to
* user-space. This allows kernel threads to set their
* priority to a value higher than any user task. Note:
* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
*/
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define MAX_PRIO (MAX_RT_PRIO + 40)
#define DEFAULT_PRIO (MAX_RT_PRIO + 20)
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
* to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
* and back.
*/
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
#define TASK_NICE(p) PRIO_TO_NICE((p)->static_prio)
static inline int rt_prio(int prio)
{
if (unlikely(prio < MAX_RT_PRIO))
return 1;
return 0;
}
static inline int rt_task(struct task_struct *p)
{
return rt_prio(p->prio);
}
0------------99 100----------139(nice +120)
实时进程 普通进程
越小优先级越高
static inline int rt_policy(int policy)
{
if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
return 1;
return 0;
}
static inline int task_has_rt_policy(struct task_struct *p)
{
return rt_policy(p->policy);
}
/*
* __normal_prio - return the priority that is based on the static prio
*/
static inline int __normal_prio(struct task_struct *p)
{
return p->static_prio;
}
/*
* Calculate the expected normal priority: i.e. priority
* without taking RT-inheritance into account. Might be
* boosted by interactivity modifiers. Changes upon fork,
* setprio syscalls, and whenever the interactivity
* estimator recalculates.
*/
static inline int normal_prio(struct task_struct *p)
{
int prio;
if (task_has_rt_policy(p))
prio = MAX_RT_PRIO-1 - p->rt_priority;
else
prio = __normal_prio(p);
return 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;
}
p->prio = effective_prio(p);
#define INIT_TASK(tsk) \
{ \
.state = 0, \
.stack = &init_thread_info, \
.usage = ATOMIC_INIT(2), \
.flags = 0, \
.lock_depth = -1, \
.prio = MAX_PRIO-20, \
.static_prio = MAX_PRIO-20, \
.normal_prio = MAX_PRIO-20, \
.policy = SCHED_NORMAL, \
.cpus_allowed = CPU_MASK_ALL, \
.mm = NULL, \
.active_mm = &init_mm,