web-dev-qa-db-ja.com

連続および並列ループ/コマンドのバッシュ

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ループを順次起動するようにします。

例として、simSeed = 1の場合、launchPower17.76 20.01 21.510 23.76と等しい状態で5つの異なるプロセスを実行する必要があります。この部分が完了したらすぐに、simSeed = 2に対してスクリプトを実行し、launchPower17.76 20.01 21.510 23.76と等しい5つの異なる並列プロセスをもう一度実行します。

どうすればこのタスクを達成できますか?

TLDR:

外部ループを順次実行し、内部ループを並列に実行して、内部ループの最後の並列プロセスが終了すると、外部ループが次の反復に移動するようにします。

3
MaJoR21

GNU Parallelには、ジョブを並行して開始するときにリソースの使用を制限するいくつかのオプションがあります。

2つのネストされたループの基本的な使用法は次のとおりです。

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 MByte

parallel --memfree 256M python <etc.>

最後のオプションは、メモリが指定された「予約」値の50%を下回ると、最後に開始されたジョブを強制終了することに注意してください(ただし、キャッチアップのために自動的に再キューイングされます)。

5
AdminBee

コメントで述べたように、これはまさにGNU parallelの用途です。

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
2
terdon

それぞれのプロセス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[@]}配列のすべての要素が待機コマンドに渡されます。

1
noAnton