2010-04-12 6 views
8

에서 파일에 비동기 쓰기 :기본적으로 내가 싶습니다 펄

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

'aio_write' 문에서 스칼라'$ a'는 입력을 저장하는 배열'@ a '와는 다른 변수입니다. – mob

+8

압축을 위해 bzip을 작성하는 경우 AIO가 필요하지 않습니다. bzip 할 파이프를 연 다음 소켓에서 (비동기 적으로) 읽고 그 데이터를 bzip 파이프에 씁니다. AnyEvent :: Handle 만 있으면됩니다. – jrockway

답변

0

Perlbal은 이와 같은 작업을 처리하는 데 관심이 있습니다. 나는 당신이하고 싶은 것과 매우 유사한 것을 성취하기 위해서 Danga::Socket을 사용한다고 믿는다.

2

비동기 적입니다 거의 항상 비동기()의 쓰기, 참고로이 배열을 데이터

물품. 물론 OS 쓰기 캐시를 채우지 않는 한.

당신은 검증되지 않은 예를 들어 일반 파이프, 시작에 비해 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); 

의 OS는 정보의 같은 양을 생성하는 것은 매우 어렵다 가장 아래를 은닉처. 파이프 라인에 bzip2가있는 경우 : HDD 성능은 압축 성능 (초당 메가 바이트 범위)보다 훨씬 높습니다 (> 50MB/s).

백그라운드로 실행하거나 여러 스트림을 병렬로 사용하려는 경우 하위 프로그램에서 fork() 및 exit()를 사용하여 메인 프로그램에 신호를 보내지 않아도 작동 방법을 알릴 필요가 없습니다.

내가 아는 한 가장 유용한 (아마도 유용한) AIO의 측면은 비동기 읽기입니다. 그것은 다른 어떤 방법으로도 달성 될 수 없습니다. 비동기 쓰기에만 AIO를 사용하는 것은 거의 의미가 없습니다.