我目前有一个bash脚本script.sh,有两个嵌套循环。第一个枚举a的可能值,第二个枚举b的可能值,如
#!/bin/sh
for a in {1..10}
do
for b in {1..10}
do
nohup python script.py $a $b &
done
done
因此,这会产生100个运行script.py的Python进程,每个进程对应一个(a,b)对。但是,我的机器只有5个内核,所以我想将进程数限制为5,以避免颠簸/浪费切换。目标是我总是运行5个进程,直到完成所有100个进程。
xargs似乎是这样做的一种方法,但我不知道如何将这些参数传递给xargs。我已经检查了其他类似的问题,但是不能理解周围的bash行话,以便知道发生了什么。例如,我试过
seq 1 | xargs -i --max-procs=5 bash script.sh
但这似乎没有做任何事情 - script.sh像以前一样运行,仍然会产生100个进程。
我认为我误解了xargs是如何工作的。
谢谢!
答案 0 :(得分:4)
这实际上看起来更像是:
#!/bin/bash
for a in {1..10}; do
for b in {1..10}; do
printf '%s\0' "$a" "$b"
done
done | xargs -0 -x -n 2 -P 5 python script.py
请注意,没有nohup
,也没有任何&
- 跟踪并发调用的数量,xargs
需要直接执行Python脚本,而且该进程不能退出直到它完成。
非标准(但可广泛使用)-0
扩展名要求输入采用NUL分隔格式(使用printf '%s\0'
创建);这确保了具有空格,引号,反斜杠等参数的正确行为。
同样非标准-P 5
设置最大进程数(比--max-procs=5
稍微更便携,GNU支持但不支持现代BSD xargs。)
-n 2
表示Python脚本的每个实例只接收两个参数,因此每对输入开始一个。
-x
(与-n 2
一起使用)表示如果单个Python实例不能给出两个参数(例如,如果参数太长以至于两者都不适合在单个命令行上),这应该被视为失败,而不是仅使用一个参数调用Python实例。
答案 1 :(得分:1)
如果您使用bash,则以下内容应该有效:
#!/bin/bash
for a in {1..10}
do
for b in {1..10}
do
if [ `jobs | wc -l` -lt 6 ]; then # less than 6 background jobs
nohup python script.py $a $b &
else
wait -n # wait for any background job to terminate
fi
done
done
答案 2 :(得分:1)
GNU Parallel适用于这些类型的工作:
parallel python script.py ::: {1..10} ::: {1..10}
如果您需要以不同的方式放置$ a和$ b,可以使用{1}和{2}来引用这两个输入源:
parallel python script.py --option-a {1} --option-b {2} ::: {1..10} ::: {1..10}
GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。它通常可以替换for
循环。
如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:
GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:
<强>安装强>
如果没有为您的发行版打包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