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引数を処理する必要があります。これを達成しますか?
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
を使用することです(ただし、これにより、さまざまなジョブからの全行が混在します)。