Linux-当高优先级任务繁忙时,不调度低优先级线程

Linux-当高优先级任务繁忙时,不调度低优先级线程,linux,linux-kernel,scheduler,cfs,Linux,Linux Kernel,Scheduler,Cfs,环境-具有linux内核2.6.18的嵌入式设备 需求-3个线程(从一个进程创建,比如P1创建T1、T2、T3) T1处于linux优先级99(最高),T2处于linux优先级50(中间),T3处于linux优先级2(最低)。没有为任何线程显式设置好的值 T1和T3都每秒递增一次变量。T1每5秒打印两个变量一次。这进展顺利。 [有问题的地方]当T2进入一个无限循环“for(;);”,T1的计数会适当增加,但T3的计数根本不会增加。 这意味着T3从未有时间在CPU中运行 在这段时间里,我一直认为l

环境-具有linux内核2.6.18的嵌入式设备 需求-3个线程(从一个进程创建,比如P1创建T1、T2、T3)

T1处于linux优先级99(最高),T2处于linux优先级50(中间),T3处于linux优先级2(最低)。没有为任何线程显式设置好的值

T1和T3都每秒递增一次变量。T1每5秒打印两个变量一次。这进展顺利。 [有问题的地方]当T2进入一个无限循环“for(;);”,T1的计数会适当增加,但T3的计数根本不会增加。 这意味着T3从未有时间在CPU中运行

在这段时间里,我一直认为linux的CFS保证所有优先级都会得到适当的份额(基于权重)。但这证明了,任何不睡觉就占用CPU的线程,都会阻止所有其他优先级较低的线程运行


如果有人知道CFS scheduler为何以这种方式运行,以及是否有办法纠正这种情况,请回答?

实时调度类始终优先于任何较低的调度类。也就是说,一个具有
SCHED_RR
的线程,如果它准备好运行,将总是使用
SCHED_OTHER
抢占一个线程。这些类只应用于执行(通常较短)紧急任务,这些任务是满足其他线程的需要、硬件的需要(如从串行端口或网卡缓冲区读取)或出于安全目的(如写入审核或日志记录条目,或提交数据库事务)所必需的。例如,用户模式设备驱动程序可能使用这些优先级,因为它们必须完成工作才能运行其他线程

类似地,在
SCHED_RR
中,如果准备就绪,优先级较高的进程将始终运行,这解释了您看到的情况

关键是:设置是关于对CPU的优先级访问而不是关于共享对CPU的访问。更高优先级总是赢。这就是优先权的含义

(为了防止病态情况的发生,实时进程在默认情况下被限制为使用95%的CPU时间。这在一个健康的系统中永远不会发生。)

如果您只是想让您的线程在常规资源中占有更大的份额,那么您应该使用
SCHED_OTHER
并使用
nice(2)
setpriority(2)
nice(2)
的值设置为负数


nice(2)
是关于共享CPU的,因为它很好地共享。

您使用的是什么SCHED策略?我们的是来自提供程序的预编译内核,大多数终端命令对我们不起作用。即使我在进程树下也看不到/proc//sched。您确定您的代码不是问题的根源吗?还要向你的提供商询问源代码和配置。我并不完全不相信你所拥有的。根据,
对于在正常调度策略之一(SCHED_OTHER、SCHED_IDLE、SCHED_BATCH)下调度的线程,SCHED_优先级在调度决策中不使用(它必须指定为0)。
因此您可以使用CFS,它是SCHED_OTHER的替代,因此不使用优先级。或者你有优先权和实时政策。在后一种情况下,您观察到的行为是正常的。为了扩展@Tsyvarev所说的内容,您所看到的行为预期适用于
SCHED_RR
SCHED_FIFO
(实时)调度策略。最高优先权获胜。如果优先级为99的线程从不阻塞,那么低优先级的线程将永远不会运行,任何其他进程(在此cpu上)也不会运行。即使是
SCHED_RR
(循环)也只是具有相同优先级的线程之间的循环。这就是@Maquefel询问您的日程安排策略的原因。除非你要求,否则你不会得到
SCHED_FIFO
/
SCHED_RR
,而且你必须是超级用户才能得到它。根据这篇文章[,即使SCHED_RR也会有一个限制,超过这个限制,SCHED_OTHER就可以运行。这似乎与你的“更高优先级的赢家,永远”背道而驰句子。你能帮我解释一下吗?我是Linux调度方面的新手。@ryuu看起来你是对的。但这个问题的答案并没有太大变化。@ryuu实时的最大时间通常是95%,如上所述。具体值在/proc/sys/kernel/sched_rt_runtime_中公开