В основном я хотел бы:
повториться..
Действительно ли это возможно? Если это возможно, я знаю, что должен буду так или иначе считать следующую передачу данных в другой массив, поскольку в документах 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;
Возможно, вас заинтересует, как Perlbal обрабатывает подобные операции. Я считаю, что он использует Danga :: Socket для выполнения чего-то очень похожего на то, что вы хотите сделать.
Асинхронная запись данных этого массива
К вашему сведению, операции 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 только для асинхронной записи имеет очень мало смысла.