为什么我在Bash中看到后台进程的速度回报递减



我正试图弄清楚为什么在Bash脚本中备份大量进程时,速度回报会递减。类似于:

function lolecho() {
echo "lol" &> /dev/null
}
c=0
while true; do
for i in $(seq 1 1000); do
lolecho &
((c+=1))
if [[ $((c%1000)) -eq 0 ]]; then
echo "Count $c"
fi
done
sleep .1
done

它尖叫着走出大门,高达1万、20万……但随后它开始放慢速度,它可以以多快的速度建立大约7万…80万的后台流程。与中一样,计数打印到屏幕的速度会减慢一个看似线性的量,具体取决于总数。

无论添加和关闭了多少后台作业,机器运行基本上立即完成的后台作业的速度难道不应该保持一致吗?

答案是使用Linux内置的等待命令:

function lolecho() {
echo "lol" &> /dev/null
}
c=0
while true; do
for i in $(seq 1 1000); do
lolecho &
((c+=1))
if [[ $((c%1000)) -eq 0 ]]; then
echo "Count $c"
fi
done
wait   # <------------
done

该脚本现在生成的进程总体上一致且更快。

注释有点长。。。OP使用wait命令的解决方案很好,但可能会微调一点。。。

按编码(在作战人员的回答中(:

  • 产生了1K后台进程(可能会对系统资源产生一些争用(
  • 我们等待所有1K过程完成,然后
  • 启动一组新的1K流程

为了获得更一致的吞吐量,我想:

  • 考虑限制并发后台进程的数量(例如,50?100?(;将需要在您的特定系统上运行一些测试(以减少系统资源争用,然后
  • 使用wait -n在进程完成后立即启动新进程

当然,对于这个简单的例子(lolecho()(来说,这可能没有太大区别,但如果做一些实际的工作,你应该会发现你保持了相当稳定的工作量。

使用wait -n的几个例子:这里和这里——见答案的后半部分

如果使用不支持-n标志的旧版本的bash,则使用轮询过程的示例

最新更新