进程优先级札记

来源:互联网 发布:淘宝夜鹰黑搜 编辑:程序博客网 时间:2024/04/29 05:09

今天查看了linux下的实时线程,FIFO和RR策略的调度,遇到一个问题:
priority越大优先级越高呢?还是越小越高呢?
 回答这个问题要明白一个问题,首先,linux2.6内核将任务优先级进行了一个划分:
 0——99  实时进程 
100——139   非实时进程
现在,这个划分是起决定作用的,而且一定是数值越小,优先级越高。

但是,有时候从网上会看到 优先级数值越大,优先级越高?这又是怎么回事?难道有一种说法错了吗?

实际的原因是这样的,对于一个实时进程,他有两个参数来表明优先级——prio 和 rt_priorityprio才是调度所用的最终优先级数值,这个值越小,优先级越高;

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,            

原创粉丝点击