Запишите асинхронно в файл в жемчуге

В основном я хотел бы:

  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;
8
задан Jonathan Leffler 12 April 2010 в 00:34
поделиться

2 ответа

Возможно, вас заинтересует, как Perlbal обрабатывает подобные операции. Я считаю, что он использует Danga :: Socket для выполнения чего-то очень похожего на то, что вы хотите сделать.

0
ответ дан 6 December 2019 в 01:39
поделиться

Асинхронная запись данных этого массива

К вашему сведению, операции write()практически всегда асинхронны. Если, конечно, вы не заполните кэш записи ОС.

Вы очень мало выиграете от использования AIO по сравнению с запуском обычного канала, например, непроверенного:

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 в pipe-line: Пропускная способность жестких дисков намного выше (>50MB/s), чем производительность сжатия (в пределах мегабайта в секунду).

Если вы хотите работать в фоновом режиме или иметь несколько потоков параллельно, не бойтесь использовать fork() и использовать exit() из дочерней программы, чтобы сообщить основной программе, как прошла операция.

Насколько мне известно, самый полезный (и, возможно, единственный полезный) аспект AIO - это асинхронное чтение. Этого нельзя достичь никаким другим способом. Использование AIO только для асинхронной записи имеет очень мало смысла.

2
ответ дан 6 December 2019 в 01:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: