これは、複数の順次処理をバックグラウンドで開始する正しい方法ですか?
for i in {1..10}; do
for j in {1..10}; do
run_command $i $j;
done &
done;
すべてのj
は指定されたi
に対して順番に処理する必要がありますが、すべてのi
は同時に処理する必要があります。
あなたが持っている外側のループは基本的に
for i in {1..10}; do
some_compound_command &
done
これにより、some_compound_command
の10個の同時インスタンスがバックグラウンドで開始されます。それらは可能な限り速く開始されますが、「すべて同時に」ではありません(つまり、some_compound_command
にvery少し時間がかかる場合、最初のものは最後のものが始まる前に終了する可能性があります) )。
some_compound_command
がループであることは重要ではありません。つまり、表示するコードは正しいであり、内側のj
- loopの反復は順次実行されますが、内側のループのすべてのインスタンス(外側の反復ごとに1つ) i
- loop)は同時に開始されます。
覚えておくべき唯一のことは、各バックグラウンドジョブがサブシェルで実行されることです。つまり、内部ループの1つのインスタンスで環境に加えられた変更(たとえば、シェル変数の値の変更、現在の作業ディレクトリのcd
による変更など)は、その特定のバックグラウンドジョブの外には表示されません。 。
追加したいのは、ループの後のwait
ステートメントで、少なくともスクリプトが終了する前に、すべてのバックグラウンドジョブが実際に終了するのを待つだけです。
for i in {1..10}; do
for j in {1..10}; do
run_command "$i" "$j"
done &
done
wait
あなたがGNU Parallelを持っているなら、あなたはそうするでしょう:
parallel -j0 'for j in {1..10}; do run_command {} $j; done' ::: {1..10}
利点の1つは、並列実行からの出力run_commands
は混合しません。