我进行了如下实验来确定这个问题:
进程1:实时优先级为40,CPU亲和力为CPU 0。这个进程“旋转”10秒钟,因此它不会让任何低优先级的进程在CPU 0上运行。
进程2:实时优先级为39,CPU亲和力为CPU 0。这个进程每0.5秒打印一条消息到标准输出,在两次打印之间休眠。它在每条消息中打印经过的时间。
我正在运行一个带有PREEMPT_RT补丁的2.6.33内核。
为了运行这个实验,我在一个窗口中(作为root用户)运行进程2,然后在另一个窗口中启动进程1(作为root用户)。结果是进程1似乎抢占了进程2,不允许它完整地运行10秒钟。
在第二个实验中,我将进程2的实时优先级更改为41。在这种情况下,进程1不会抢占进程2。
这个实验表明,在sched_setscheduler()
中使用更大的实时优先级值具有更高的优先级。这似乎与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()
设置的实时优先级。
简答
99将成为实时优先级的获胜者。
PR是优先级等级(范围从-100到39)。 PR越低,进程的优先级就越高。
PR的计算如下:
详细回答
有两种类型的进程,即普通进程和实时进程。仅对普通进程应用“好”的规则如下:
好
"好"尺度从-20到19,其中-20是最高优先级,19是最低优先级。优先级等级的计算如下:
PR = 20 + NI
其中NI是好的水平,而PR是优先级水平。因此,我们可以看到-20实际上映射到0,而19映射到39。
默认情况下,程序的好价值是0,但是超级用户可以使用以下命令启动具有指定好价值的程序:
nice -n <nice_value> ./myProgram
实时性
我们可以更进一步。优先级的好处实际上是用于用户程序的。而UNIX/LINUX整体优先级有140个值的范围,良好的优先级值使该进程能够映射到范围的最后部分(从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
调度过程可以分为两组,常规调度策略(1到3)和实时调度策略(4和5)。 实时进程将始终优先于常规进程。可以使用以下命令调用实时进程(以下示例是如何声明SCHED_RR策略的):
chrt --rr <priority between 1-99> ./myProgram
为了得到实时进程的PR值,应使用以下方程:
PR = -1 - rt_prior
其中rt_prior对应于1到99之间的优先级。因此,将具有比其他进程更高优先级的进程称为以数字99调用的进程。
重要的是要注意,对于实时进程,不使用美好值。
要查看进程的当前“niceness”和PR值,可以执行以下命令:
top
以下是显示的输出:
该图显示了PR和NI值。值得注意的是,具有实时值对应的PR值为-51的进程。还有一些进程其PR值被说明为“rt”。 实际上,这个值对应于-100的PR值。
在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。
Linux内核实现了两个不同的优先级范围 -
Nice值:-20至+19;较大的 Nice 值对应着 较低的优先级。
实时优先级:0至99;较高的 实时优先级值对应着 更高的优先级。
你认为正常进程的静态优先级从100到139是不稳定的,最坏的情况下是无效的。我的意思是:set_scheduler只允许使用SCHED_OTHER / SCHED_BATCH和SCHED_IDLE(截至2.6.16),sched_priority为0(表示动态优先级调度程序)。
在编程上,静态优先级仅适用于SCHED_RR和SCHED_FIFO,范围为1-99。
现在你可能会看到动态调度程序内部使用了100-139的优先级,但是内核在管理动态优先级时所做的操作(包括翻转高优先级与低优先级的含义以使比较或排序更容易)应该对用户空间不透明。
请记住,在SCHED_OTHER中,您主要将进程放入相同的优先级队列中。
这样做的想法是使内核更易于调试并避免愚蠢的越界错误。
因此,切换含义的理由可能是作为内核开发人员,不想使用像139-idx这样的数学公式(以防idx>139)...最好使用idx-100进行数学计算,并反转低优先级与高优先级的概念,因为idx<100是众所周知的。
另一个副作用是niceness变得更容易处理。 100-100 <=> nice == 0; 101-100 <=> nice == 1; 等等更容易。 它也很好地折叠为负数(与静态优先级无关)。 99-100 <=> nice == -1 ...
我们确实有40作为批处理、其他策略的非实时进程优先级计数,范围为0-39而不是100至139。您可以通过查看系统中任何不是实时进程的进程来观察到这一点。默认情况下,它将具有20的PR和0的niceness。如果您降低进程的niceness(通常是越小或负数的数字表示进程越饥饿),例如从0到-1,则会发现优先级从20下降到19。 这只是告诉您,如果您让进程更加饥饿或希望通过降低PID的niceness值获得更多关注,您也会获得优先级的降低,因此优先级数字越低,优先级越高。
示例:
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