Bash:バックグラウンドで複数のforループ

Bash:バックグラウンドで複数のforループ

これがバックグラウンドで複数のシーケンシャルプロセスを開始する正しい方法ですか?

for i in {1..10}; do
    for j in {1..10}; do
        run_command $i $j;
    done &
done;

場合によっては、すべてをj順次処理する必要がありますiが、すべてをi同時に処理する必要があります。

答え1

あなたが持っている外部ループは基本的に

for i in {1..10}; do
    some_compound_command &
done

some_compound_commandこれにより、バックグラウンドで10個の同時インスタンスが起動されます。できるだけ早く開始されますが、正確には「同時」(some_compound_command必要な場合など)ではありません。非常に時間が短い場合は、最後のジョブが開始される前に最初のジョブが完了する可能性が高くなります。

それがループであるという事実はsome_compound_command重要ではありません。つまり、表示されるコードは次のようになります。正しい内部jループの繰り返しは順次実行されますが、内部ループのすべてのインスタンス(i外部ループの各繰り返しごとに1つ)が同時に開始されます。

覚えておくべき唯一のことは、各バックグラウンドジョブがサブシェルで実行されることです。これは、内部ループの1つのインスタンス内で行われた環境の変更(たとえば、現在の作業ディレクトリへの変更を使用してシェル変数の値を変更するcdなど)が特定のバックグラウンドタスクの外部に表示されないことを意味します。

wait少なくともスクリプトが終了する前に、すべてのバックグラウンドジョブが実際に完了するのを待つために、ループの後にステートメントを追加できます。

for i in {1..10}; do
    for j in {1..10}; do
        run_command "$i" "$j"
    done &
done

wait

答え2

GNU Parallelがある場合は、次のことができます。

parallel -j0 'for j in {1..10}; do run_command {} $j; done' ::: {1..10}

1つの利点は、並列実行の出力がrun_commands混在しないことです。

関連情報