我想使用我制作的 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 个不同的并行进程,其等于.launchPower
17.76 20.01 21.510 23.76
simSeed = 2
launchPower
17.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 命令。