如何使从perl脚本到gzip文件的写入成为非阻塞?

如何使从perl脚本到gzip文件的写入成为非阻塞?,perl,nonblocking,Perl,Nonblocking,我目前正在编写一个脚本,它将数据库作为输入,并根据特定规则从10+个表中生成所有有效的组合。由于输出非常巨大,我通过gzip将其转储到文件中,如下所示: open( my $OUT, '|-', "gzip > file" ); for ( @data ) { my $line = calculate($_); print $OUT $line; } 由于野兽的本性,我最终不得不写成千上万的小文章,每行一篇。这意味着在每次计算之间,它会等待gzip接收数据并完成压缩。至少

我目前正在编写一个脚本,它将数据库作为输入,并根据特定规则从10+个表中生成所有有效的组合。由于输出非常巨大,我通过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字节。:)