2017-08-11 46 views
0

我有以下bash腳本,它並行啓動一個程序幾次並將控制變量傳遞給每個執行。 該程序利用了多個資源,所以在它並行啓動10次之後,我想等到最後10個啓動完成。等待最後10個並行啓動的作業在bash中完成

我目前正在做這個非常粗略的工作,只需等待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

如果你要跟蹤是否程序成功或失敗,您將需要存儲他們的PID。 PID和'idx'之間的關聯數組映射特別有用,因爲它可以讓你知道哪個'idx's成功和失敗了。 –

+0

順便說一下,這種方法作爲一個整體通常效率很低 - 在批次中的第一個程序完成時和最後一個程序完成時,通常會有一堆浪費的CPU時間。最好使用'for((k = start; k

+0

@CharlesDuffy謝謝你,我看到那篇文章,並且我不太清楚,由於使用了一個異步設備,它依賴於等待時間來完成作業,所以我的情況是否可以關閉。但是,您的答案是否已經提供了等待該程序或僅用於啓動? – Kev1n91

回答

2

好吧,既然你已經到位,檢查10次迭代(idx % 10)有一個代碼,該wait內置似乎完美。從該文檔:

wait: wait [-n] [id ...]

[...]等待由一個ID,其可以是進程ID或 作業規範中確定的每個處理,並報告其終止狀態。 如果給出的ID不是 ,則等待所有當前活動的子進程,並且返回 狀態爲零。

因此,通過wait每次idx % 10 == 0,您實際上正在等待所有以前的子進程完成。如果你沒有產生任何其他的東西,那麼你會等待那些(最多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 
+0

比你真的,我只需要將代碼從「睡眠10」更改爲「等待」 – Kev1n91

+0

是的,就是這樣。 :) – randomir

+1

我已經添加了一些替代品,如果這適用於您的用例。 – randomir