コマンドラインオプションなしで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
機能しません。代わりに、parallel
STDINへの入力を永遠に待つのをブロックするようです。パイプを修正すると、デッドロックprintfifos | head -n4 | parallel cat
が消え、最初の4つのパイプが正常に印刷されます。
この動作はパラメータに関連しているようです--jobs|-j
。{ yes | ghead -n5; sleep 10; } | parallel cat
10秒間出力は生成されませんが、オプションを追加すると、4-j1
本のラインが生成され、y
ほぼ直ちに最後になりますy
。すべてparallel
EOFを取得するために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
(ただし、他のタスクの行全体を混在させます)。