在多核上编译时,什么可能导致 make 挂起?

use*_*424 18 linux compiling make

昨天我试图从源代码编译ROOT包。由于我是在 6 核怪物机器上编译它,因此我决定继续使用make -j 6. 一开始编译很顺利,速度也很快,但在某个时候make,只在一个内核上使用了 100% 的 CPU。

我做了一些谷歌搜索,并在 ROOT 留言板上找到了这篇文章。自从我自己组装了这台电脑,我担心我没有正确应用散热器和CPU过热什么的。不幸的是,我在工作时没有可以把它塞进去的冰箱。;-)

我安装了lm-sensors软件包并make -j 6再次运行,这次是监控 CPU 温度。尽管它变得很高(接近 60 C),但它从未超过高温或临界温度。

我尝试运行make -j 4make在编译过程中的某个时候再次挂起,这次是在不同的位置。

最后,我编译运行make并运行良好。我的问题是:它为什么挂了?由于它停在两个不同的位置,我猜这是由于某种竞争条件,但我认为make应该足够聪明,以正确的顺序排列所有东西,因为它提供了-j选项。

Sté*_*nez 15

对于这个确切的问题,我没有答案,但我可以尝试给您一些可能发生的情况的提示:Makefiles 中缺少依赖项。

例子:

target: a.bytecode b.bytecode
    link a.bytecode b.bytecode -o target

a.bytecode: a.source
    compile a.source -o a.bytecode

b.bytecode: b.source
    compile b.source a.bytecode -o a.bytecode
Run Code Online (Sandbox Code Playgroud)

如果你调用make target一切都会正确编译。a.source首先执行编译(任意地,但确定性地)。然后b.source执行编译。

但是如果你make -j2 target两个compile命令将并行运行。你实际上会注意到你的 Makefile 的依赖关系被破坏了。第二个编译假定a.bytecode已经编译,但它没有出现在依赖项中。所以很可能会发生错误。正确的依赖行b.bytecode应该是:

b.bytecode: b.source a.bytecode
Run Code Online (Sandbox Code Playgroud)

回到你的问题,如果你不走运,一个命令可能会因为缺少依赖关系而在 100% CPU 循环中挂起。这可能就是这里发生的事情,顺序构建无法显示丢失的依赖项,但您的并行构建已显示它。