並列に実行されるxargsコマンドの出力順序を保持する

並列に実行されるxargsコマンドの出力順序を保持する

並列実行コマンドを実行すると、xargs -n 1 -P 0出力はすべて混乱します。並列実行を実行する方法がありますが、2番目の実行の出力が開始される前に最初の実行の出力全体がstdoutに書き込まれ、3番目の実行の出力が開始される前に2番目の実行の完全な出力がstdoutに書き込まれていることを確認してください。開始待ち始めますか?

たとえば、大量のデータを含む大量のファイルをハッシュしたい場合は、次のようにします。

printf "%s\0" * | xargs -r0 -n 1 -P 0 sha256sum

少量のデータ(9GB)でテストしましたが、わずか5.7秒で終わりました。以下を使用して同じデータをハッシュします。

sha256sum *

34.1秒かかりました。大量のデータをハッシュする必要がある場合が多いため(数時間かかる場合があるため)、並列処理によりジョブがより早く完了します。

ここでの問題は、出力ラインの順序が間違っていることです。この場合、2番目の列に基づいて行を並べ替えると問題が解決します。しかし、必ずしも簡単ではありません。たとえば、上記のハッシュの例に従うが、番号付きファイルを順次ハッシュしたい場合、これはすでに中断されます。

printf "%s\0" {1..10000} | xargs -r0 -n 1 -P 0 sha256sum

これには、より高度なソートが必要です。ハッシュの例を完全に逸脱すると、状況はより複雑になります。

コメントで、誰かが出力がインターリーブされるのを防ぎたいかどうか尋ねました。そうではありません。秩序を維持したい。

ベストアンサー1

これを達成するためにGNU Parallel()を使用できます--keep-order

printf "%s\0" {1..10000} | parallel --keep-order -r0 -n 1 -P 0 sha256sum

--keep-order各プロセスは4つのファイルハンドルを使用するため、印刷が遅れます。これにより、通常、遅延は発生しません。

たとえば、1000 個のファイルハンドルがあり、1 つのジョブが平均ジョブより 250 倍以上かかる場合、GNU Parallel は 996 個のファイルハンドルを使用して追加の操作を実行します。長期実行ジョブが完了していないままになると、GNU Parallelはファイルハンドルが不足して長期実行ジョブが完了するのを待ちます。次のように警告します。

parallel: Warning: No more file handles.
parallel: Warning: Try running 'parallel -j0 -N 100 --pipe parallel -j0'
parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
parallel: Warning: or increasing /proc/sys/fs/file-max

これにより、長い操作が完了するまで一時停止します。データ損失はありません。

おすすめ記事