Bash并行化CPU密集型进程

tee将stdin转发给指定的每个文件,而pee则是相同的,但是对于pipe道。 这些程序将stdin的每一行发送到指定的每个文件/pipe道。

然而,我正在寻找一种方式来“平衡”标准input到不同的pipe道,所以一行发送到第一个pipe道,另一行到第二个,等等。如果收集pipe道标准输出也是很好的也成为一个stream。

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

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

要并行化,最好的情况是,如果GNU parallel支持这样的function(由--demux-stdin选项组成):

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

然而,没有这样的select, 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版本的东西,但这也可以。

我们正在讨论如何在GNU Parallel的邮件列表上正确地实现这个functionhttp://lists.gnu.org/archive/html/parallel/2011-01/msg00001.html

随意join: http : //lists.gnu.org/mailman/listinfo/parallel

原型现在已经可以进行testing了: http : //lists.gnu.org/archive/html/parallel/2011-01/msg00015.html

我会考虑在Parallel :: ForkManager中用 Perl来实现这个function 。 您可以在脚本中进行分行,然后将结果行input到Parallel :: ForkManager进程中。 使用run_on_finishcallback来收集输出。 显然,对于你的sed例子,你可以在perl中执行文本操作,也可以使用AnyEvent来处理并行性。