我有以下bash脚本,它并行启动程序几次并将控制变量传递给每次执行。 该程序使用了多个资源,因此在并行启动10次后,我想等到最后10次启动,完成。
我目前正在大致这样做,只需等待10次迭代,最长时间可能完成10个并行启动的程序。
是否有直接的方法来实现此行为?
steps=$((500/20))
echo $steps
START=0
for((i=START;i < steps; i++))
do
for((j=START;j < steps;j++))
do
for((k=START;k < steps;k++))
do
n=$(($j*steps +$k))
idx=$(($i*$steps*$steps + $n))
if ! ((idx % 10)); then
echo "waiting for the last 10 programs"
sleep 10
else
./someprogram $idx &
fi
done
done
done
答案 0 :(得分:2)
好吧,既然你已经有了一个代码来检查第10次迭代(idx % 10
),那么wait
内置似乎是完美的。来自文档:
wait: wait [-n] [id ...]
[...]等待由ID标识的每个进程,可以是进程ID或 工作规范,并报告其终止状态。 如果ID不是 给定,等待所有当前活动的子进程,以及返回 状态为零。
因此,每次wait
idx % 10 == 0
,您实际上都在等待所有以前的子进程完成。如果你没有产生除someprogram
以外的任何东西,那么你将等待那些(最多10个)最后完成。
您的脚本wait
:
#!/bin/bash
steps=$((500/20))
START=0
for ((i=START; i<steps; i++)); do
for ((j=START; j<steps; j++)); do
for ((k=START; k<steps; k++)); do
idx=$((i*steps*steps + j*steps + k))
if ! ((idx % 10)); then
wait
else
./someprogram $idx &
fi
done
done
done
另外,请注意,您不必在算术扩展$var
中使用$((var+1))
(美元前缀)。
我假设您的实际脚本在调用someprogram
之前执行了一些额外的处理,但如果您只需要在连续索引上调用someprogram
,一次调用10个实例,您可以考虑使用xargs
或GNU parallel
。
例如,使用xargs
:
seq 0 1000 | xargs -n1 -P10 ./someprogram
或者,使用someprogram
的其他参数:
seq 0 1000 | xargs -n1 -P10 -I{} ./someprogram --option --index='{}' someparam
使用GNU parallel
:
seq 0 1000 | parallel -P10 ./someprogram '{}'
seq 0 1000 | parallel -P10 ./someprogram --option --index='{}' someparam