2010-04-12 14 views
8

में दाखिल करने के लिए मूल रूप से मैं करना चाहते हैं:एसिंक्रोनस रूप से लिखें पर्ल

  1. स्मृति में एक सरणी में नेटवर्क से डेटा की एक बड़ी राशि पढ़ें।
  2. असीमित रूप से इस सरणी डेटा को लिखते हैं, इसे डिस्क पर हिट करने से पहले bzip2 के माध्यम से चलाते हैं।

दोहराने ..

यह संभव है? यदि यह संभव है, तो मुझे पता है कि मुझे किसी भी प्रकार के डेटा को किसी भिन्न सरणी में पढ़ना होगा क्योंकि एआईओ दस्तावेज़ कहते हैं कि एसिंक लिखने से पहले इस सरणी को बदला नहीं जाना चाहिए। मैं डिस्क पर अपने सभी लिखने की पृष्ठभूमि को पृष्ठभूमि में रखना चाहता हूं क्योंकि bzip2 पास नेटवर्क पढ़ने से काफी अधिक समय ले रहा है।

क्या यह करने योग्य है? नीचे जो मुझे लगता है उसकी एक सरल उदाहरण नीचे दी गई है, लेकिन यह परीक्षण के लिए सरणी @ ए में फ़ाइल को पढ़ती है।

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' 'सरणी' @ ए 'से एक अलग चर है जो इनपुट रखता है। – mob

+8

यदि आप संपीड़न के लिए bzip लिख रहे हैं, तो आपको एआईओ की भी आवश्यकता नहीं है। Bzip करने के लिए एक पाइप खोलें, और फिर सॉकेट (असीमित रूप से) से पढ़ें और उस डेटा को bzip पाइप पर लिखें। AnyEvent :: हैंडल आपको बस चाहिए। – jrockway

उत्तर

0

आप में कैसे Perlbal इस तरह के आपरेशनों संभालती दिलचस्पी हो सकती है। मेरा मानना ​​है कि यह कुछ ऐसा करने के लिए Danga::Socket का उपयोग करता है जो आप करना चाहते हैं।

2

एसिंक्रोनस रूप से इस सरणी डेटा

FYI लिखते हैं, लिखने() रों काफी हमेशा अतुल्यकालिक कर रहे हैं। बेशक आप ओएस लिखने कैश भरें।

आप एक सादे पाइप, जैसे, अपरीक्षित शुरू करने की तुलना में 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 होने के साथ कम: एचडीडी थ्रूपुट संपीड़न प्रदर्शन (प्रति सेकंड मेगाबाइट्स की सीमा में) की तुलना में बहुत अधिक (> 50 एमबी/एस) है।

यदि आप इसे पृष्ठभूमि में चलाने के लिए या समानांतर में कई धाराएं चलाना चाहते हैं, तो फोर्क() से कोई डर नहीं है और बच्चे से निकास() का उपयोग मुख्य कार्यक्रम को सिग्नल करने के लिए किया जाता है कि ऑपरेशन कैसे चल रहा था।

मेरे ज्ञान के लिए एआईओ का सबसे उपयोगी (और शायद केवल उपयोगी) पहलू एसिंक्रोनस पढ़ता है। यह किसी भी अन्य तरीके से हासिल नहीं किया जा सकता है। एआईओ का उपयोग केवल एसिंक लिखने के लिए बहुत कम समझ में आता है।

संबंधित मुद्दे