STDINで引数を実行する前にGNU Parallelが遅延しないように設定する

STDINで引数を実行する前にGNU Parallelが遅延しないように設定する

コマンドラインオプションなしで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

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

この動作はパラメータに関連しているようです--jobs|-j{ yes | ghead -n5; sleep 10; } | parallel cat10秒間出力は生成されませんが、オプションを追加すると、4-j1本のラインが生成され、yほぼ直ちに最後になりますyすべてparallelEOFを取得するためにSTDINを読み取って、以前に処理するパラメータを取得できます。これを達成する方法はありますか?

答え1

GNU Parallelのバグは、ワークスロットごとに1つのジョブを読み込んだ後にのみ処理を開始することです。その後、一度に1つのジョブを読みます。

以前のバージョンでは、ワークスロットの数に応じて出力も遅れていました。最新バージョンでは、単一ジョブの出力のみが遅延されます。

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

開始タイムアウトに対する解決策は、並列処理のためにワークスロットあたりのダミージョブを提供することです。

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(ただし、他のタスクの行全体を混在させます)。

関連情報