2011-12-04 1 views
4

は、私は戻って、私は、彼らが完全に後にそれらを送っ同じ順序で回答を得る並列にHTTPリクエストの一握り、例えばを実行するための簡単な方法を探しています:どのようにしてPerlで並列HTTP要求を行い、順番にそれらを受け取るのですか? Perlの使用

my ($google, $perl) = foobar(GET => 'http://www.google.com/', 
          GET => 'http://www.perl.org/'); 

があります私が見ているは​​ずのモジュールですか?

私は手で簿記をすることができると知っていますが、jQuery's when methodを使ってこれを実行できるようになった後には恥ずかしく感じます。私はPerlを使った単純な解決策が大好きです。

ありがとうございました。

+0

FWIW:私はちょうどLWPを取得しようとしました::最後の2時間の並列作業と私の髪を引っ張っている。私はLWP :: Parallelをまったくお勧めしません。それは非常にバギーで、APIとドキュメントだけでなく欠けているようです。 – jlh

答えて

13
use threads; 
use LWP::UserAgent qw(); 

my $ua = LWP::UserAgent->new(); 
my @threads; 
for my $url ('http://www.google.com/', 'http://www.perl.org/') { 
    push @threads, async { $ua->get($url) }; 
} 

for my $thread (@threads) { 
    my $response = $thread->join; 
    ... 
} 

最良の部分は、すべての要求が完了するために親が待機していないということです。正しい要求が完了するとすぐに、親はブロックを解除して処理します。


あなたがParallel::ForkManagerたり、特定の子のために待つことができない何か他のものを使用した場合、あなたは結果を注文するには、次のコードを使用することができますが:

for my $id (0..$#urls) { 
    create_task($id, $urls[$id]); 
} 

my %responses; 
for my $id (0..$#urls) { 
    if (!exists($responses{$id})) { 
     my ($id, $response) = wait_for_a_child_to_complete(); 
     $responses{$id} = $response; 
     redo; 
    } 

    my $response = delete($responses{$id}); 
    ... 
} 
+0

Parallel :: ForkManagerの例もどうですか? – ysth

+1

@ysth、P :: FMのポイントは、固定サイズの労働者プールで働くことです。それはCPUを共有するのに良いことです。この場合、すべての人がIOを待っているので、OPは可能な限り多くのワーカーを必要とします。 (スレッドの代わりにプロセスが必要な場合は、 'use threads;'を 'forks;'に変更してください。) – ikegami

+0

@ysth、P :: FMで使用できる順序付けアルゴリズムを追加しました。 – ikegami

10

私はMojoのファンです。 Mojo::UserAgentドキュメントから :

use Mojo; 
use Mojo::UserAgent; 
# Parallel requests 
my $ua = Mojo::UserAgent->new; 
$ua->max_redirects(5); 
my $delay = Mojo::IOLoop->delay; 
for my $url ('http://www.google.com/', 'http://www.perl.org/') { 
    $delay->begin; 
    $ua->get($url => sub { 
    my ($ua, $tx) = @_; 
    $delay->end($tx->res->dom); 
    }); 
} 
my @responses = $delay->wait; 
print join "\n", @responses 

お楽しみください!

EDITところで

。あなたが間にそれを行うことができ、最後に応答を処理する必要はありません。

# ... 
$ua->get($url => sub { 
    my ($ua, $tx) = @_; 
    $delay->end(1); 
    # process $tx->res here 
}); 
# ... 
$delay->wait; 
+1

今年は[Perl Advent Calendar](http://perladvent.org)のエントリーがありますが、どの日になるのか分かりません。 –

+0

@brian d foy、esskarの解決策では、親は応答を処理する前に、必要以上に長く待っています。簡単に修正できますか? – ikegami

関連する問題