今天早些时候,当我构建一些东西时,我决定make
运行
$ make -j
也许是出于对其他程序的习惯,例如cabal
默认-j
为合理的限制。
大约20秒后,我的整个桌面都停止运转了。我寻找各种活动迹象。没有风扇旋转。 HDD 指示灯呈绿色常亮,但我没有听到磁盘活动的声音。嗯嗯。沉默了 10 分钟后,我终于看到了对很久以前按下的第一个按键的响应,而且我也开始听到非常熟悉的磁盘敲击声。 20 分钟后,我慢慢地尝试进入这台没有反应的机器上的终端,最后我屈服并使用了 REISUB。
起初,我认为罪魁祸首一定是一个不相关的桌面应用程序,因为我早就有了交互式 bash 会话的内存限制以免我陷入这种境地!但/var/log/syslog
讲述了一个不同的故事; OOM 杀手留下的痕迹一些ps
垃圾场哪些是可疑的包装的与c++
和cc1plus
过程!
以下是其中一个转储的频率分析:
Command Number of appearances
'sh' 322
'c++' 321
'cc1plus' 321
'chrome' 27
'make' 27
'bash' 3
all else combined 120
所以我检查了 GNU make 的手册页:(添加了强调)
-j [jobs], --jobs[=jobs] 指定同时运行的作业(命令)数量。如果有多个 -j 选项,则最后一个有效。 如果给出的 -j 选项不带参数,make 将不会限制可以同时运行的作业数量。
我不愿意看看是否可以重现该问题(医生,我做的时候很痛这...),但到目前为止的调查结果似乎是一个全垒打:显然,make -j
数百个由此产生的进程一定是挂起和磁盘抖动的原因。也就是说,在互联网上搜索,我找不到太多针对它的警告。我是否过早下结论?
make -j
真像我想象的那么危险吗? 如果是这样,到底为什么它在那里吗?可以采取什么措施来防止它被白痴使用?
答案1
有些工具可以让您以多种富有想象力的方式搬起石头砸自己的脚。这样你就可以发挥你的想象力来解决问题,而不受别人认为“理智”的限制。
运行make -j
一个小项目是完全合理的。在其他项目中,-j
不带参数的使用会严重削弱系统的响应能力。在某些项目中,使用并行构建,即使使用-j2
,也会完全破坏构建(由并行 make 进程创建的文件不能及时出现在另一个进程中,等等)。
我个人会避免使用别名make
(make -j4
正如您在评论中所说的那样)。我发现最好明确地告诉机器要做什么,这样我就可以知道它会做什么。几天后,我就会忘记这个别名,并想知道为什么我在不同终端中构建的四个项目使我的系统无响应。
至于“危险”……这个词在不同的语境下有不同的含义。是的,它是“危险的”,因为它可能会使系统失去响应。是的,它是“危险的”,因为它很可能在构建过程中使构建过程崩溃。但不,它并不“危险”,因为它会重新格式化您的硬盘或开始删除随机文件。
那么,如何防白痴呢?
这是一个可靠的分步指南:
- 学习使用你的工具。
另请注意,-j
BSD 标志make
做需要一个参数,并且这个标志是非标准的(Unix POSIX 标准没有提到它)。
答案2
您还可以使用以下命令限制 make -l
:
-l [load], --load-average[=load] 指定如果有其他作业正在运行且平均负载至少为 load(浮点数),则不应启动新作业(命令)。不带参数,删除先前的负载限制。
但请注意,像这样运行它似乎没有帮助:make -j -l4
。
在平均负载超过限制之前启动了太多作业(根据我的经验)。因此,组合可以起作用,例如make -j8 -l4
。