【问题标题】:Which real-time priority is the highest priority in LinuxLinux中哪个实时优先级最高
【发布时间】:2012-02-11 20:06:56
【问题描述】:

在 Linux 实时进程优先级范围 1 到 99 中,我不清楚哪个是最高优先级,1 还是 99。

“了解 Linux 内核”(O'Reilly) 的第 7.2.2 节说 1 是最高优先级,考虑到普通进程的静态优先级从 100 到 139,这是有道理的,其中 100 是最高优先级:

"每个实时进程都关联一个实时优先级,该优先级范围从 1(最高 优先级)到 99(最低优先级)。 "

另一方面,sched_setscheduler 手册页 (RHEL 6.1) 声称 99 是最高的:

"根据实时策略之一(SCHED_FIFO、SCHED_RR)调度的进程 sched_priority 值在 1(低)到 99(高)的范围内。"

哪个是最高实时优先级?

【问题讨论】:

    标签: linux linux-kernel real-time


    【解决方案1】:

    您认为正常进程具有从 100 到 139 的静态优先级的假设充其量是不稳定的,而在最坏的情况下是无效的。我的意思是:set_scheduler 只允许 sched_priority 为 0(表示动态优先级调度程序)与 SCHED_OTHER / SCHED_BATCH 和 SCHED_IDLE(从 2.6.16 开始为真)。

    仅 SCHED_RR 和 SCHED_FIFO 以编程方式静态优先级为 1-99

    现在您可能会看到动态调度程序在内部使用 100-139 的优先级,但是内核在内部执行了哪些操作来管理动态优先级(包括翻转高优先级和低优先级的含义以使比较或排序更容易)应该对用户空间不透明。

    请记住,在 SCHED_OTHER 中,您主要将进程填充在同一个优先级队列中。

    这个想法是让内核更容易调试并避免愚蠢的越界错误。

    所以切换含义的基本原理可能是作为内核开发人员不想使用像 139-idx 这样的数学(以防 idx > 139)......最好用 idx-100 和颠倒低与高的概念,因为 idx

    还有一个副作用是友好变得更容易处理。 100 - 100 不错 == 0; 101-100 不错 == 1;等更容易。它也可以很好地折叠为负数(与静态优先级无关)99 - 100 nice == -1 ...

    【讨论】:

    • 好的,我看到 sched_priority 与静态优先级不同,所有非实时进程的 sched_priority 都是 0。
    • 所以静态优先级只影响实时进程的时间量。我相信 sched_priority 就是 O'Reilly 书中所说的“实时优先级”。如果是这样,O'Reilly 的书就倒退了。那么,回到我原来的问题:sched_priority 为 99 是最高优先级,还是 1 是最高优先级?
    【解决方案2】:

    要确定您可以通过编程设置的最高实时优先级,请使用 sched_get_priority_max 函数。

    在 Linux 2.6.32 上,调用 sched_get_priority_max(SCHED_FIFO) 返回 99。

    http://linux.die.net/man/2/sched_get_priority_max

    【讨论】:

    • 与 OP 的问题更相关,来自同一个手册页:“优先级数值较高的进程排在优先级数值较低的进程之前”。
    【解决方案3】:

    sched.h 中的这条评论非常明确:

    /*
     * 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.
     */
    

    注意这部分:

    优先级值倒置:p->prio 值越低表示优先级越高

    【讨论】:

    • 但是那些暴露给用户空间的优先级值是否相同? (我不相信)。
    • @davmac:不,它们完全不同。这些是内核内部的。
    • 对。这本书似乎在谈论这些值,因为我认为用户空间无法访问单个等效的优先级值。在这种情况下,这本书只有一个细节错误(假设 MAX_PRIO=139 和 MAX_RT_PRIO=99):最高优先级值是 0,而不是 1。(赞成:你的答案是重点)。
    【解决方案4】:

    我做了一个实验来确定这一点,如下:

    • 进程 1:RT 优先级 = 40,CPU 亲和性 = CPU 0。此进程“旋转”10 秒,因此它不会让任何低优先级进程在 CPU 0 上运行。

    • process2:RT 优先级 = 39,CPU 亲和性 = CPU 0。此进程每 0.5 秒向 stdout 打印一条消息,在其间休眠。它打印出每条消息的经过时间。

    我正在运行带有 PREEMPT_RT 补丁的 2.6.33 内核。

    为了运行实验,我在一个窗口中(以 root 身份)运行 process2,然后在另一个窗口中启动 process1(以 root 身份)。结果是 process1 似乎抢占了 process2,不允许它运行整整 10 秒。

    在第二个实验中,我将 process2 的 RT 优先级更改为 41。在这种情况下,process2 被 process1 抢占。

    这个实验表明 sched_setscheduler() 中的更大 RT 优先级值具有更高的优先级。这似乎与 Michael Foukarakis 从 sched.h 中指出的相矛盾,但实际上并非如此。在内核源代码的sched.c 中,我们有:

    static void
    __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
    {
            BUG_ON(p->se.on_rq);
    
            p->policy = policy;
            p->rt_priority = prio;
            p->normal_prio = normal_prio(p);
            /* we are holding p->pi_lock already */
            p->prio = rt_mutex_getprio(p);
            if (rt_prio(p->prio))
                    p->sched_class = &rt_sched_class;
            else
                    p->sched_class = &fair_sched_class;
            set_load_weight(p);
    }
    

    rt_mutex_getprio(p) 执行以下操作:

    return task->normal_prio;
    

    而 normal_prio() 恰好做了以下事情:

    prio = MAX_RT_PRIO-1 - p->rt_priority;  /* <===== notice! */
    ...
    return prio;
    

    换句话说,我们有(我自己的解释):

    p->prio = p->normal_prio = MAX_RT_PRIO - 1 - p->rt_priority
    

    哇!这令人困惑!总结一下:

    • 使用 p->prio,较小的值会抢占较大的值。

    • 使用 p->rt_priority,较大的值会抢占较小的值。这是使用 sched_setscheduler() 设置的实时优先级。

    【讨论】:

      【解决方案5】:
      1. 当然,实时优先级适用于从 0-99 变化的 RT 策略 FIFO 和 RR。
      2. 我们确实将 40 作为 BATCH 的非实时进程优先级的计数,其他策略从 0-39 而不是从 100 到 139。这一点,您可以通过查看系统中的任何进程来观察不是实时过程。默认情况下,它将承受 20 的 PR 和 0 的 NIceness。如果你降低进程的 niceness(通常,降低或负数,niceness 越小,进程越饿),比如从 0 到 -1,你会观察到优先级将从 20 下降到 19。 这只是说明,如果您让进程更加饥饿,或者想通过降低 PID 的 niceness 值来获得更多关注,那么您的优先级也会降低,从而降低 PRIORITY 数字更高的优先级。

        Example:
        
        PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
        2079 admin     10 -10  280m  31m 4032 S  9.6  0.0  21183:05 mgmtd
        [admin@abc.com ~]# renice -n -11 2079
        2079: old priority -10, new priority -11
        [admin@abc.com ~]# top -b | grep mgmtd
        2079 admin      9 -11  280m  31m 4032 S  0.0  0.0  21183:05 mgmtd
        ^C
        

      希望这个实际示例能够澄清疑问,并可能有助于修正来源不正确的单词(如果有的话)。

      【讨论】:

        【解决方案6】:

        简答

        99 将成为实时优先的赢家。

        PR 是优先级(范围 -100 到 39)。 PR越低,进程的优先级越高。

        PR 计算如下:

        • 对于正常进程:PR = 20 + NI(NI 很好,范围从 -20 到 19)
        • 对于实时进程:PR = - 1 - real_time_priority (real_time_priority 范围从 1 到 99)

        长答案

        有两种类型的进程,正常实时 对于普通的(并且仅适用于那些),nice 的应用如下:

        不错

        “好”等级从 -20 到 19,而 -20 是最高优先级,19 是最低优先级。优先级计算如下:

        公关 = 20 + NI

        其中 NI 是 nice 级别,PR 是优先级。所以我们可以看到,-20 实际上映射到 0,而 19 映射到 39。

        默认情况下,程序 nice 值为 0 位,root 用户可以使用以下命令来午餐具有指定 nice 值的程序:

        nice -n <nice_value> ./myProgram 
        

        实时

        我们可以走得更远。 nice 优先级实际上用于用户程序。尽管 UNIX/LINUX 总体优先级的值范围为 140,但 nice 值使进程能够映射到范围的最后一部分(从 100 到 139)。此等式使 0 到 99 的值无法达到,这将对应于负 PR 级别(从 -100 到 -1)。为了能够访问这些值,该过程应声明为“实时”。

        LINUX环境下有5个调度策略,可以用如下命令显示:

        chrt -m 
        

        这将显示以下列表:

        1. SCHED_OTHER   the standard round-robin time-sharing policy
        2. SCHED_BATCH   for "batch" style execution of processes
        3. SCHED_IDLE    for running very low priority background jobs.
        4. SCHED_FIFO    a first-in, first-out policy
        5. SCHED_RR      a round-robin policy
        

        调度进程可以分为2组,正常调度策略(1到3)和实时调度策略(4和5)。 实时进程总是优先于正常进程。可以使用以下命令调用实时进程(示例是如何声明 SCHED_RR 策略):

        chrt --rr <priority between 1-99> ./myProgram
        

        为了获得实时过程的 PR 值,应用以下等式:

        PR = -1 - rt_prior

        其中 rt_prior 对应于 1 到 99 之间的优先级。因此,优先级高于其他进程的进程将是编号为 99 的进程。

        需要注意的是,对于实时进程,nice 值没有被使用。

        要查看进程的当前“niceness”和 PR 值,可以执行以下命令:

        top
        

        显示以下输出:

        图中显示了 PR 和 NI 值。最好注意 PR 值 -51 对应于实时值的过程。还有一些进程的 PR 值用“rt”表示。这个值实际上对应的PR值是-100。

        【讨论】:

        • 适合在 chrt 上寻找实时日程安排的快速答案的人。对于 chrt,1 的优先级最低,99 的优先级最高。我很惊讶 chrt 的手册页中没有提到它。
        • 我无法建议进一步的编辑,但我相信这个答案中有一些小的矛盾细节。答案从“PR = 20 - NI”开始,PR 值范围从 -100 到 40。但后来,它说“PR = 20 + NI”,PR 值范围从 -100 到 39。我是相对确信后者(即 PR = 20 +NI 并且从 -100 到 39)是正确的!
        • @KenLin 是的,有一个错误,但实际上恰恰相反。 PR = 20 + NI。已更正,谢谢指出。
        • 我仍然看到“PR 是优先级(范围 -100 到 40)”。 40 不应该是 39 吗?
        【解决方案7】:

        Linux 内核实现了两个独立的优先级范围 -

        1. 不错的值:-20 到 +19; 较大的不错的值对应于较低的优先级

        2. 实时优先级:0 到 99; 更高的实时优先级值对应于更高的优先级

        【讨论】:

        • 感谢您的帮助,但您可以通过解释这两个优先级之间的关系来改进答案。例如,添加详细信息实时优先级范围和非实时范围如何重叠,以及“nice”优先级在此上下文中指的是什么。
        猜你喜欢
        • 1970-01-01
        • 2017-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多