我在bash中有一个可并行化的for循环,并希望限制并行运行的作业数。脚本如下所示:
#!/usr/bin/env bash
num_cores=25
num_jobs=100
for ((i = 0; i < num_jobs; i++)); do
while read -r -a curr_jobs < <(jobs -p -r) \
&& ((${#curr_jobs[@]} >= num_cores)); do
wait -n
done
NAME=job_$i
screen -S $NAME -d -m bash -c "my bash command"
done
该脚本基于the answer基于stackoverflow上的类似问题。但不同之处在于,当我在循环中调用Python
时,在该答案中调用了screen
。由于我不知道的某些原因,此解决方案看起来与screen
不兼容。
如何修改脚本以限制并行screen
会话数?
这个问题是否有更简单/更好的解决方案?
答案 0 :(得分:1)
使用GNU Parallel和tmux
:
seq 100 | parallel -j25 -N0 --tmux my bash command
示例:为每个CPU核心运行一次休眠:
seq 100 | parallel --tmux "echo Running {} Job sequence {#}; sleep {}"
GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。
如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:
GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:
<强>安装强>
出于安全原因,您应该使用软件包管理器安装GNU Parallel,但如果没有为您的发行版打包GNU Parallel,则可以进行个人安装,这不需要root访问权限。这可以在10秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解详情
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
答案 1 :(得分:0)
前段时间我做过这样的事情:
#!/bin/bash
FILE=$1
tmpVAR=0
while read line; do
ScriptTakingArgFromFile.sh $line & PID1=$!
tmpVAR=$[$tmpVAR+1]
if [ "$tmpVAR" -eq 50 ]
then tmpVAR=0
# echo "STOP 50"
wait $PID1
fi
done < $FILE
wait $PID1
这将执行51个进程并停止。然后当进程号51结束时将触发另一个51。
如果您希望始终拥有一定数量的进程,则始终可以将pid写入数组,并在数组具有所需长度时停止。写入检查这些PID并在进程结束时从数组中删除它们,然后数组将收缩,另一个进程将被触发。
希望有所帮助。