2010-04-12 47 views
8

içinde dosyaya uyumsuz yazın:Temelde ben istiyorum perl'de

  1. belleğe bir diziye ağdan veri büyük miktarda okuyun.
  2. Bu dizi verilerini, diske ulaşmadan önce bzip2 ile çalıştırarak eşzamansız olarak yazın. Bu mümkün

tekrar ..

mi? Eğer bu mümkün ise, bir sonraki veriyi farklı bir diziye okumak zorunda kalacağım, çünkü AIO dokümanları bu dizinin async yazma tamamlanmadan önce değiştirilmemesi gerektiğini söylüyor. Bzip2 pass'ın okunan ağdan daha uzun süreceği için tüm yazımları diske kaydetmeyi isterim.

Bu yapılabilirlik? Aşağıda, ihtiyaç duyduğum şeyin basit bir örneği var, ancak bu, test için array @a dosyasına bir dosya okuyor.

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

"aio_write" ifadesindeki scalar 'a a', girdiyi tutan 'a 'dizisinden farklı bir değişkendir. – mob

+8

Sıkıştırma için bzip yazıyorsanız, AIO'ya bile ihtiyacınız yoktur. Bzip yapmak için bir boru açın ve sonra soketten (eşzamansız) okuyun ve bu verileri bzip borusuna yazın. AnyEvent :: Handle ihtiyacınız olan her şeydir. – jrockway

cevap

0

Sen Perlbal bu gibi işlemleri nasıl işleyeceğini ilginizi çekebilir. Yapmak istediğiniz şeye çok benzeyen bir şey gerçekleştirmek için Danga::Socket'u kullandığını düşünüyorum.

2

uyumsuz olan hemen hemen her zaman asenkron() ler yazma, Bilginize bu dizi veri

yazın. Tabii OS yazma önbelleğini doldurmazsanız.

Sen denenmemiş mesela düz boru, başlangıç ​​ile karşılaştırıldığında AIO'yu kullanmaktan çok az kazanabilir: yazma dolmaya olarak

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

işletim o bilginin bu miktarları üretmek çok zor çoğu Altında önbelleği. Boru hattında bzip2 olması en az: HDD'lerin performansı, sıkıştırma performansından (saniyede megabayt aralığında) çok daha yüksektir (> 50MB/s).

Arka planı çalıştırmak veya paralel olarak birden çok akışa sahip olmak istiyorsanız, fork() 'dan korkmayın ve ana bilgisayardan ana programa çıkış işleminin nasıl devam ettiğini öğrenin.

Bildiğim kadarıyla AIO'nun en kullanışlı (ve muhtemelen sadece kullanışlı) yönü asenkron okumalardır. Bu başka bir şekilde elde edilemez. AIO'yu sadece uyumsuz yazma için kullanmak çok az anlam ifade eder.

İlgili konular