Bash 连续和并行循环/命令

Bash 连续和并行循环/命令

我想使用我制作的 Python 工具运行一些模拟。问题是我必须使用不同的参数/参数和所有内容多次调用它。

目前,我正在使用多个for循环来执行任务,例如:

for simSeed in 1 2 3 4 5
do
    for launchPower in 17.76 20.01 21.510 23.76
    do
        python sim -a $simSeed -p $launchPower
    done
done

为了使模拟同时运行,我&在调用模拟器的行末尾附加了一个。

python sim -a $simSeed -p $launchPower &

使用这种方法,我可以运行多个这样的种子。但是,由于我的计算机内存有限,我想重写上面的脚本,以便它并行启动内for循环,顺序启动外for循环。

例如,对于,我希望 5 个不同的进程以等于 的方式simSeed = 1运行。一旦这部分完成,我希望脚本再次运行 5 个不同的并行进程,其等于.launchPower17.76 20.01 21.510 23.76simSeed = 2launchPower17.76 20.01 21.510 23.76

我怎样才能完成这个任务?

总括:

我希望外循环顺序运行,内循环并行运行,这样当内循环的最后一个并行进程完成时,外循环移动到下一个迭代。

答案1

GNU并行有几个选项来限制并行启动作业时的资源使用。

两个嵌套循环的基本用法是

parallel python sim -a {1} -p {2} ::: 1 2 3 4 5 ::: 17.76 20.01 21.510 23.76

例如,如果您想同时启动最多 5 个作业,您可以说

parallel -j5 python <etc.>

或者,您可以使用该--memfree选项仅在有足够的可用内存(例如至少 256 MB)时启动新作业

parallel --memfree 256M python <etc.>

请注意,如果内存低于规定的“保留”值的 50%,最后一个选项将终止最近启动的作业(但它将自动重新排队以进行追赶)。

答案2

正如评论中提到的,这正是 GNUparallel的用途:

for simSeed in 1 2 3 4 5
do
    ## Launch 5 instances in parallel 
    parallel -j5 python sim -a $simSeed -p {} ::: 17.76 20.01 21.510 23.76
done

答案3

您可以存储相应的进程 ID 并wait让它们完成:

for simSeed in {1..5}; do
  pids=()
  for launchPower in 17.76 20.01 21.510 23.76; do
    python sim -a $simSeed -p $launchPower &
    pids+=($!)
  done
  wait ${pids[@]}
done

pids是内部循环后台作业的进程 ID 数组。${pids[@]}数组的所有元素都传递给 wait 命令。

相关内容