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


8

これは、複数の順次処理をバックグラウンドで開始する正しい方法ですか?

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

すべてがj与えられたため、互いの後に処理されなければならないiが、すべてをi同時に処理する必要があります。


「正しい方法」とはどういう意味ですか?
Eran Ben-Natan、

主にそれが動作すること。私はstackoverflowでこれを見逃していました。
ラジコン、

1
:-)私はあなたのコードが私のためにうまく機能するので私は尋ねています。「正しい方法」であなたがベストプラクティスを意味するならば、私には、より明確になるよう機能、さらには別のファイルに内部ループを置く
エランベン・ナタン

回答:


8

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

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

これによりsome_compound_command、の10個の同時インスタンスがバックグラウンドで開始されます。彼らは(場合つまり、できるだけ速くとしてスタートし、ではなく、かなり「すべてを同時に」されますsome_compound_command要する非常に少しの時間を、最初はうまく最後の1が開始される前に終了してもよいです)。

実際にsome_compound_commandループであることを起こるは重要ではありません。あなたが示すことのコードがあることをこの意味正しい内部のそれの繰り返しでj-loopが順次実行されますが、内側のループ(外側の反復あたり1のすべてのインスタンスi-loop)が同時に開始されるだろう。

覚えておくべき唯一のことは、各バックグラウンドジョブがサブシェルで実行されることです。つまりcd、内部ループの1つのインスタンスで環境に加えられた変更(たとえば、シェル変数の値の変更、現在の作業ディレクトリの変更など)は、その特定のバックグラウンドジョブの外部からは見えません。

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

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

wait

3

GNU Parallelを使用している場合は、次のようにします。

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.