如果我输入两个不同的根终端:
nice -n 19 burnK7 &
和
nice -n -19 burnK7 &
然后两个进程都会获得大约 50% 的可用 CPU 时间——这并不在意料之中,当然也不是我们所希望的。
如果我跑在相同的根终端:
nice -n 19 burnK7 &
nice -n -19 burnK7 &
正如预期的那样,第一个进程获得大约 0% 的可用 CPU 时间,而第二个进程获得大约 100% 的可用 CPU 时间。
这是一个错误还是一个功能?
我正在单核机器上运行内核版本 3.16 的 Arch Linux,看看它的价值。
答案1
所以,事后,这里有一些信息。您看到的行为是由于 Linux 2.6.38(2010 年)中添加的自动分组功能。这是我即将添加到sched(7)
手册页这解释了您所看到的情况。
内核提供了一个称为自动分组的功能,用于在面对多进程、CPU 密集型工作负载(例如使用大量并行构建进程构建 Linux 内核)时提高交互式桌面的性能(即标志make(1) -j
)。
当通过 创建新会话时,将创建一个新的自动组setsid(2)
;例如,当启动新的终端窗口时,就会发生这种情况。通过 创建的新进程fork(2)
将继承其父进程的自动组成员身份。因此,会话中的所有进程都是同一自动组的成员。
启用自动分组后,自动组的所有成员都会被放在同一个内核调度程序“任务组中”。Linux 内核调度程序采用一种算法来均衡任务组中 CPU 周期的分配。以下示例可以描述此算法对交互式桌面性能的好处。
假设有两个自动组竞争同一个 CPU(即,假设使用单 CPU 系统或使用 将taskset(1)
所有进程限制在 SMP 系统上的同一个 CPU 上)。第一个组包含十个 CPU 绑定进程,它们来自以 开始的内核构建make -j10
。另一个组包含一个 CPU 绑定进程:视频播放器。自动分组的效果是两个组将各自获得一半的 CPU 周期。也就是说,视频播放器将获得 50% 的 CPU 周期,而不是仅仅 9% 的周期,这可能会导致视频播放质量下降。SMP 系统上的情况更为复杂,但总体效果是一样的:调度程序在任务组之间分配 CPU 周期,以便包含大量 CPU 绑定进程的自动组不会以牺牲系统上其他作业为代价而占用 CPU 周期。
超值优惠和团体安排
在调度非实时进程(例如,在默认SCHED_OTHER
策略下调度的进程)时,调度程序采用一种称为“组调度”的技术,在该技术下,线程被调度到“任务组中”。任务组在各种情况下形成,这里相关的情况是自动分组。
如果启用了自动分组,则所有(隐式)放置在自动组中的线程(即由 创建的同一会话setsid(2)
)将形成一个任务组。因此,每个新的自动组都是一个单独的任务组。
在组调度下,线程的 nice 值会影响调度决策仅相对于同一任务组中的其他线程。这在 UNIX 系统上 nice 值的传统语义方面产生了一些令人惊讶的后果。特别是,如果启用了自动分组(这是各种发行版中的默认设置),则nice(1)
对进程的采用仅对相对于在同一会话中执行的其他进程(通常是:同一个终端窗口)的调度有影响。
相反,对于两个进程,例如,它们是不同会话中唯一的 CPU 绑定进程(例如,不同的终端窗口,每个窗口的作业都与不同的自动组绑定),修改其中一个会话中进程的 nice 值对调度程序相对于另一个会话中的进程的决策没有影响。
如果您想防止自动分组干扰nice
此处描述的传统行为,您可以禁用该功能
echo 0 > /proc/sys/kernel/sched_autogroup_enabled
但请注意,这也会禁用自动分组功能旨在提供的桌面交互优势(参见上文)。
自动分组 nice 值
可以通过该文件查看进程的自动组成员身份/proc/[pid]/autogroup
:
$ cat /proc/1/autogroup
/autogroup-1 nice 0
此文件还可用于修改分配给自动组的 CPU 带宽。这是通过将“nice”范围内的数字写入文件来设置自动组的 nice 值来实现的。允许的范围是从 +19(低优先级)到 -20(高优先级)。
自动组 nice 设置与进程 nice 值含义相同,但适用于根据其他自动组的相对 nice 值将 CPU 周期分配给整个自动组。对于自动组内的进程,它收到的 CPU 周期将是自动组的 nice 值(与其他自动组相比)和进程的 nice 值(与同一自动组中的其他进程相比)的乘积。