如何防止自己在编译时意外指定过多的线程?

如何防止自己在编译时意外指定过多的线程?

当我编译东西时,我通常希望快速完成,因此在我的工作站上我发出

make -j16

然后 (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。然后我应该在中止时进行更改猜测

答案1

您不需要编写任何特殊的 Makefile 来确定核心数量;可以在环境和 Linux 中指定默认标志核心工具附带一个名为的工具nproc

export MAKEFLAGS="-j$(nproc)"

如果nproc你的系统中不存在,另一种选择(也仅适用于 Linux)是getconf

export MAKEFLAGS="-j$(getconf _NPROCESSORS_ONLN)"

可以通过make在低 CPU 和 IO 优先级下运行(以及整个构建过程)来部分防止完全冻结:

alias make="nice ionice make"

但请注意,如果其他进程同时大量使用磁盘 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 "$@"
}

相关内容