等待最后10个并行开始的工作以bash结束

时间:2017-08-11 16:55:18

标签: bash parallel-processing

我有以下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

1 个答案:

答案 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个实例,您可以考虑使用xargsGNU 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