Bash CPU 密集型进程的并行化

Bash CPU 密集型进程的并行化

tee将其标准输入转发到指定的每个文件,而pee执行相同操作,但针对管道。这些程序将其标准输入的每一行发送到指定的每个文件/管道。

但是,我正在寻找一种方法来将标准输入“负载平衡”到不同的管道,因此一行被发送到第一个管道,另一行被发送到第二个管道,等等。如果管道的标准输出也被收集到一个流中,那就太好了。

用例是对逐行工作的 CPU 密集型进程进行简单的并行化。我正在处理sed一个 14GB 的文件,如果我可以使用多个进程,它可以运行得更快sed。命令如下:

pv infile | sed 's/something//' > outfile

为了并行化,最好的办法是GNU并行将像这样支持此功能(组成选项--demux-stdin):

pv infile | parallel -u -j4 --demux-stdin "sed 's/something//'" > outfile

但是,没有这样的选项,并且parallel总是使用其 stdin 作为其调用的命令的参数,例如xargs。所以我尝试了这个,但它非常慢,原因很明显:

pv infile | parallel -u -j4 "echo {} | sed 's/something//'" > outfile

我只是想知道是否有其他方法可以做到这一点(除了自己编写代码)。如果有“负载平衡” tee(我们称之为lee),我可以这样做:

pv infile | lee >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile)

不太漂亮,所以我绝对更喜欢虚构的parallel版本,但这也可以。

答案1

我们正在讨论如何在 GNU Parallel 的邮件列表中实现此功能http://lists.gnu.org/archive/html/parallel/2011-01/msg00001.html

欢迎加入:http://lists.gnu.org/mailman/listinfo/parallel

原型现已准备好进行测试:http://lists.gnu.org/archive/html/parallel/2011-01/msg00015.html

答案2

我会考虑用 Perl 来实现Parallel::ForkManager。您可以在脚本中进行行拆分,然后将结果行输入到 Parallel::ForkManager 进程中。使用回调run_on_finish来收集输出。显然,对于您的 sed 示例,您可以改为在 perl 中执行文本操作,也许可以使用类似任何事件处理并行性。

相关内容