web-dev-qa-db-ja.com

Make GNU Parallelは、STDINから引数を実行する前に遅延しません

GNU Parallelを使用すると、コマンドラインオプションを使用せずに、最後の引数がSTDINの行によって決定されるコマンドを簡単に並列化できます。

$ seq 3 | parallel echo
2
1
3

parallelはジョブの実行を開始する前にSTDINでEOFを待機しないことに注意してください— yes | parallel echoを実行すると、yのコピーが無限に多く印刷されます。離れて。

ただし、STDINが比較的短い場合、この動作は変化するように見えます。

$ { yes | ghead -n5; sleep 10; } | parallel echo

この場合、sleep 10が完了するまで出力は返されません。

これは単なる例です。実際には、継続的に生成される一連のFIFOパイプから、既存のパイプが消費され始めるまでFIFO生成プロセスが続行されない)を読み取ろうとしています。たとえば、私のコマンドは次のようなSTDOUTストリームを生成します。

/var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.PFcggGR55i
/var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.UCpTBzI3J6
/var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.r2EmSLW0t9
/var/folders/2b/1g_lwstd5770s29xrzt0bw1m0000gn/T/tmp.5TRNeeZLmt

これらの各ファイルを新しい端末で一度に1つずつ手動でcat-すると、FIFO生成プロセスが正常に完了します。ただし、printfifos | parallel catの実行は機能しません。代わりに、parallelはSTDINでの入力を待機することを永久にブロックしているようです—パイプラインをprintfifos | head -n4 | parallel catに変更すると、デッドロックが消え、最初の4つのパイプが正常に出力されます。

この動作は、--jobs|-jパラメーターに関連しているようです。 { yes | ghead -n5; sleep 10; } | parallel catは10秒間出力を生成しませんが、-j1オプションを追加すると、ほぼ直後に4行のyが生成され、その後に最後のyが10秒間待機します。残念ながら、これでは問題は解決しません— parallelがSTDINの読み取りからEOFを取得する前に、every引数を処理する必要があります。これを達成しますか?

3
goodside

GNU Parallelのバグは、ジョブスロットごとに1つのジョブを読み取った後にのみ処理を開始し、その後は一度に1つのジョブを読み取るというものです。

古いバージョンでは、ジョブスロットの数によって出力も遅延します。新しいバージョンでは、単一のジョブによる出力のみが遅延します。

したがって、1秒あたり1つのジョブをparallel -j10に送信すると、開始する前に10個のジョブが読み取られます。古いバージョンでは、ジョブ3からの出力が表示されるまで、さらに10秒待つ必要があります。

開始時の制限の回避策は、ジョブスロットごとに1つのダミージョブを並列にフィードすることです。

true >jobqueue; tail -n+0 -f jobqueue | parallel &
seq $(parallel --number-of-threads) | parallel -N0 echo true >> jobqueue
# now add the real jobs to jobqueue

出力の回避策は、--linebufferを使用することです(ただし、これにより、さまざまなジョブからの全行が混在します)。

2
Ole Tange