perl - 在perl中异步写入文件

标签 perl asynchronous io

基本上我想:

  1. 将大量数据从网络读取到数组中并存入内存。
  2. 异步写入此数组数据,在其到达磁盘之前通过 bzip2 运行它。

重复..

这可能吗?如果这是可能的,我知道我将不得不以某种方式将下一次数据读取到不同的数组中,因为 AIO 文档说在异步写入完成之前不得更改该数组。我想按顺序将所有写入磁盘的操作放在后台,因为 bzip2 传递将比网络读取花费更长的时间。

这可行吗?下面是我认为需要的一个简单示例,但这只是将文件读取到数组 @a 中进行测试。

use warnings;
use strict;
use EV;
use IO::AIO;
use Compress::Bzip2;
use FileHandle;
use Fcntl;


my @a;

print "loading to array...\n";
while(<>) {
  $a[$. - 1] = $_;
}
print "array loaded...\n";


my $aio_w = EV::io IO::AIO::poll_fileno, EV::WRITE, \&IO::AIO::poll_cb;


aio_open "./out", O_WRONLY || O_NONBLOCK, 0, sub {
  my $fh = shift or die "error while opening: $!\n";

  aio_write $fh, undef, undef, $a, -1, sub {
    $_[0] > 0 or die "error: $!\n";
    EV::unloop;
  };
};

EV::loop EV::LOOP_NONBLOCK;

最佳答案

Asynchronously write this array data

仅供引用,write() 几乎总是异步的。当然,除非您填满操作系统写入缓存。

与启动普通管道(例如未经测试的管道)相比,使用 AIO 获得的 yield 非常少:

my $socket; # INET something
my $out = new IO::Handle;
open($out, "|bzip2 > ./out") || die;
while (1) {
  my $buf;
  $socket->recv($buf, 64*1024, 0);
  last unless defined $buf and length $buf;
  print $out $buf;
}
close($out);

在大多数操作系统下,很难生成足以填满写入缓存的信息量。至少在管道中使用 bzip2 时:HDD 吞吐量 (>50MB/s) 远高于压缩性能(每秒兆字节范围)。

如果您想在后台运行它或并行运行多个流,请不要担心 fork() 并使用子程序中的 exit() 来向主程序发出操作如何继续的信号。

据我所知,AIO 最有用(也可能是唯一有用)的方面是异步读取。这是任何其他方式都无法实现的。仅使用 AIO 进行异步写入没有什么意义。

关于perl - 在perl中异步写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2619292/

相关文章:

perl - 如何在非类包中重载运算符?

c - 从标准输入读取()

html - Perl 正则表达式模式匹配

linux - 在使用 ("6/16"时不能使用字符串 "strict refs") 作为哈希引用

perl - 除非明确包含,否则阻止包含 Perl 模块

javascript - async/await 比 promises 慢吗?

java - 如果返回失败的阶段,为什么 thenCombine 结果不会异常完成?

javascript - 测试复杂的异步 Redux 操作

java - 读取重文本文件

java - 为什么 "fileInputStream.read()"的值会改变呢?