如何使从perl脚本到gzip文件的写入成为非阻塞?
我目前正在编写一个脚本,它将数据库作为输入,并根据特定规则从10+个表中生成所有有效的组合。由于输出非常巨大,我通过gzip将其转储到文件中,如下所示:如何使从perl脚本到gzip文件的写入成为非阻塞?,perl,nonblocking,Perl,Nonblocking,我目前正在编写一个脚本,它将数据库作为输入,并根据特定规则从10+个表中生成所有有效的组合。由于输出非常巨大,我通过gzip将其转储到文件中,如下所示: open( my $OUT, '|-', "gzip > file" ); for ( @data ) { my $line = calculate($_); print $OUT $line; } 由于野兽的本性,我最终不得不写成千上万的小文章,每行一篇。这意味着在每次计算之间,它会等待gzip接收数据并完成压缩。至少
open( my $OUT, '|-', "gzip > file" );
for ( @data ) {
my $line = calculate($_);
print $OUT $line;
}
由于野兽的本性,我最终不得不写成千上万的小文章,每行一篇。这意味着在每次计算之间,它会等待gzip接收数据并完成压缩。至少我这么认为,我可能错了
如果我是对的,我想知道如何使这个打印异步,也就是说,它在gzip激发数据,然后继续处理数据。当然,我会按照您的意愿用线程或叉子来完成。
试试看。它接受一个要写入的对象。您可以在该文件句柄上执行操作。管道已经使用了缓冲区,因此写入程序不必等待读取程序。但是,该缓冲区通常相当小(在Linux上通常只有64KB),并且不容易更改(它需要重新编译内核)。如果标准缓冲区不够,最简单的方法是在管道中包含缓冲程序:
open( my $OUT, '|-', "bfr | gzip > file" );
只需将STDIN读入内存缓冲区,并以下一个程序允许的速度写入STDOUT即可。默认为5MB缓冲区,但您可以使用
-b
选项(例如,对于10MB缓冲区,bfr-b10m
)。“线程”号。不是在Perl中。试图在Perl中使用线程只会导致厄运和眼泪。如果Fork不会破坏我的调试器(我不在Windows上),它将是一个选项。eads to doom and weats:我会记住它:)(我从未使用过它)另一个解决方案(但不是在Windows下)是制作类似系统的东西(“gzip-$line&”);这似乎相当危险,因为这意味着为每一行编写一个gzip实例,并将它们附加到同一个文件中,这意味着它们很容易遇到覆盖或交错彼此输出的问题。此外,由于这是纯IO,我想有一些方法可以做到这一点,而不会滥用操作系统的进程创建功能我希望如此:)。此外,“系统”调用可能比gzip行更昂贵。恐怕在Perl中进行压缩与我想要的完全相反。不过O_Non Block这件事很有趣。我只是不知道是否可以将它应用到另一个进程的管道中。上次我对它进行基准测试时,使用IO::Compress::Gzip比生成Gzip
进程要慢得多。谢谢!我不在那个缓冲区附近,通过管道连接到gzip的一条线路的长度为850字节。:)