2010-04-12 16 views
8

Básicamente me gustaría:escribo de forma asíncrona a presentar en Perl

  1. Leer una gran cantidad de datos de la red en una matriz en la memoria.
  2. Escribe asincrónicamente esta matriz de datos, ejecutándola a través de bzip2 antes de que llegue al disco.

repita ..

es esto posible? Si esto es posible, sé que tendré que leer de alguna manera la próxima serie de datos en una matriz diferente, ya que los documentos de AIO dicen que esta matriz no se debe modificar antes de que se complete la escritura asíncrona. Me gustaría poner en segundo plano todas mis escrituras en el disco en orden, ya que el pase bzip2 va a tomar mucho más tiempo que la lectura de la red.

¿Es esto factible? A continuación se muestra un ejemplo simple de lo que creo que se necesita, pero esto simplemente lee un archivo en array @ a para probar.

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; 
+1

El escalar '$ a' en la declaración' aio_write' es una variable diferente de la matriz '@ a' que contiene la entrada. – mob

+8

Si está escribiendo en bzip para compresión, ni siquiera necesita AIO. Abra una tubería para bzip, y luego lea desde el zócalo (asíncronamente) y escriba esa información en la tubería bzip. AnyEvent :: Handle es todo lo que necesitas. – jrockway

Respuesta

0

Usted puede estar interesado en la forma en Perlbal se encarga de las operaciones de esta manera. Creo que usa Danga::Socket para lograr algo muy similar a lo que quieres hacer.

2

asincrónica escribir esta matriz de datos

su información, escribir() s son casi siempre asíncrona. A menos que, por supuesto, llene el caché de escritura del sistema operativo.

Ganarías muy poco el uso de la AIO en comparación con iniciar un tubo liso, por ejemplo, no probado:

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); 

En la mayoría sistemas operativos es muy difícil generar tales cantidades de información como para llenar la escritura cache. Al menos con tener bzip2 en la línea de tubería: el rendimiento de la HDD es mucho mayor (> 50MB/s) que el rendimiento de la compresión (en el rango de megabytes por segundo).

Si desea que se ejecute de fondo o tener varios flujos en paralelo, no tienen miedo a tenedor() y utilizar la salida() de niño a señalar programa principal forma en la operación continuó.

Que yo sepa, el aspecto más útil (y probablemente solo útil) de AIO son las lecturas asíncronas. Eso no se puede lograr de ninguna otra manera. Usar AIO para solo escribir de manera asíncrona tiene muy poco sentido.

Cuestiones relacionadas