哪个实时优先级是Linux中的最高优先级
在Linux实时进程优先权范围1至99中,我不清楚哪一个是最高优先级,1或99。
“理解Linux内核”的第7.2.2节(O'Reilly)认为1是最高优先级,考虑到正常进程的静态优先级从100到139,其中100是最高优先级:
“每个实时过程都与实时优先级相关联,实时优先级从1(最高优先级)到99(最低优先级)。”
另一方面,sched_setscheduler手册页(RHEL 6.1)声称99是最高的:
“在其中一个实时策略(SCHED_FIFO,SCHED_RR)下计划的进程的sched_priority值的范围为1(低)到99(高)。
哪个是最高的实时优先级?
我做了一个实验,如下所示:
-
process1:RT优先级= 40,CPU亲和力= CPU 0.此进程“旋转”10秒,因此不会让任何优先级较低的进程在CPU 0上运行。
-
process2:RT优先级= 39,CPU亲和力= CPU 0.此进程每隔0.5秒打印一条消息到stdout,在两者之间hibernate。 它打印每个消息的经过时间。
我使用PREEMPT_RT补丁运行2.6.33内核。
为了运行实验,我在一个窗口中运行process2(以root身份),然后在另一个窗口中启动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()设置的实时优先级。
在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
值表示较高的优先级 。
要确定可以通过编程方式设置的最高实时优先级,请使用sched_get_priority_max函数。
在Linux 2.6.32上,对sched_get_priority_max(SCHED_FIFO)的调用返回99。
假设正常进程的静态优先级从100到139是不稳定的,最坏的情况是无效的。 我的意思是说:set_scheduler只允许SCHED_OTHER / SCHED_BATCH和SCHED_IDLE(从2.6.16起为true)的sched_priority为0(表示dynamic优先级调度器)。
对于SCHED_RR和SCHED_FIFO,编程静态优先级仅为1-99
现在,您可能会看到dynamic调度程序在内部使用100-139的优先级,但是内核在内部做什么来pipe理dynamic优先级(包括翻转高优先级和低优先级的含义以使比较或sorting更容易)应该是不透明的到用户空间。
请记住,在SCHED_OTHER中,您大多将进程填充到相同的优先级队列中。
这个想法是使内核更容易debugging,并避免愚蠢的错误。
因此,切换意义的理由可能是,作为一个内核开发人员不希望使用math像139-IDX(以防万一IDX> 139)…这是更好的做与idx-100math和扭转的概念低与高,因为idx <100是很好理解。
另外一个副作用是善良变得更容易处理。 100 – 100 <=> nice == 0; 101-100 <=> nice == 1; 等等更容易。 它很好地倒塌到负数(没有做与静态优先级)99 – 100 <=>不错== -1 …
- 绝对地,实时优先级适用于从0-99变化的RT策略FIFO和RR。
-
我们确实有40个作为BATCH非实时进程优先级的计数,其他策略在0-39之间,而不是从100到139之间。您可以通过查看系统中不是实时的任何进程处理。 它将默认承担20的PR和0的感度。 如果你减less一个过程的好处(通常数字越低,数字越小,过程越饥渴),比如从0到-1,你会发现PRiority会从20下降到19。如果你使一个过程更加饥饿,或者希望通过降低PID的好坏值来获得更多的关注,那么你的优先级也会降低,从而将优先级数字降低到更高的优先级。
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
希望这个实际的例子澄清疑惑,并可能有助于修复错误的来源,如果有的话。