mat*_*ath 2 freeze make threads
当我编译东西时,我通常想快速完成,所以在我的工作站上我发出
make -j16
Run Code Online (Sandbox Code Playgroud)
并且 (gnu) make 开始使用 16 个内核进行编译。但是,当我回到笔记本电脑上时,那里没有 16 个内核。因此,当我在那里发出相同的命令时,我的机器会死机。我无法通过 CTRL+ALT+F1 等切换到备用终端,远程登录也不会成功。CTRL+C, CTRL+4 都不考虑。(顺便说一句:没有自动杀死会成功,例如自动内存不足)然后我必须关闭我的机器。(我使用带有内核 3.0.x 的 Ubuntu 11.10)
一种解决方案是预先获得当前机器上可用的内核数量,并使用一个小的 make 目标,而任何其他“并行”目标都依赖于并且不直接使用“make -j $NUMCORES”。(我已经这样做了,并通过一个使用 boost 线程的小型 c++ 程序实现了)。但这不会保护我不小心再次指定“make -j16”。
此外,“太多”内核不能与可用内核数量(包括线程内核)相同,因为 +1 或 +2 线程仍然不会杀死机器。
我可以使用 ulimits 来缓解这个问题吗?我想指定将交换空间设置为 0。然后我应该改变中止我猜。
您不需要编写任何特殊的 Makefile 来确定内核数量;可以在环境中指定默认标志,Linux coreutils带有一个名为的工具nproc:
export MAKEFLAGS="-j$(nproc)"
Run Code Online (Sandbox Code Playgroud)
如果nproc您的系统中不存在,则替代方案(也仅适用于 Linux)是getconf:
export MAKEFLAGS="-j$(getconf _NPROCESSORS_ONLN)"
Run Code Online (Sandbox Code Playgroud)
可以通过make以低 CPU 和 IO 优先级运行(以及整个构建过程)来防止完全冻结:
alias make="nice ionice make"
Run Code Online (Sandbox Code Playgroud)
但是请注意,如果其他进程同时大量使用磁盘 IO 或 CPU,这将减慢编译速度。
您还可以编写一个包装脚本(或一个 shell 函数)来检查给它的所有参数:
make() {
local arg
for arg; do
[[ $arg == -j* ]] && {
echo "Rejecting '$arg' in make args. Use 'command make ...' to bypass."
return 1
}
done
command make "$@"
}
Run Code Online (Sandbox Code Playgroud)