保留 xargs 并行执行的命令的输出顺序

保留 xargs 并行执行的命令的输出顺序

当我运行用于并行执行的命令时xargs -n 1 -P 0,输出都是混乱的。有没有办法进行并行执行,但要确保在第二次执行的输出开始之前将第一次执行的整个输出写入stdout,第二次执行的整个输出在第三次执行的输出之前写入stdout执行开始等?

例如,当想要对包含大量数据的许多文件进行哈希处理时,可以这样做:

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

我在少量数据 (9 GB) 上进行了测试,只用了 5.7 秒就完成了。使用散列相同的数据

sha256sum *

花了34.1秒。我经常需要对大量数据进行哈希处理(这可能需要几个小时),因此并行处理可以更快地完成工作。

这里的问题是输出行的顺序错误。在这种情况下,只需按第二列对行进行排序即可解决此问题。但这并不总是那么容易。例如,如果坚持上面的散列示例,但想要按顺序散列编号的文件,这已经会中断:

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 个文件句柄,并且单个作业的耗时超过平均作业的 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

然后将暂停,直到冗长的工作完成。不会有数据丢失。

相关内容