您之前在评论中提出了这个问题,以询问有关按照请求发出的顺序收集响应的问题,并且您发布的代码是从该问题的答案中复制的。因此,我认为这也是您想要的。
以下不是最有效的解决方案,因为没有线程重用,但它可以很容易地按照您想要的顺序收集响应。
use threads;
use LWP::UserAgent qw( );
my @urls = ...;
my $ua = LWP::UserAgent->new();
my @threads;
for (1..200) {
last if !@urls;
my $url = shift(@urls);
push @threads, async { $ua->get($url) };
}
while (@threads) {
my $thread = shift(@threads);
my $response = $thread->join;
if (@urls) {
my $url = shift(@urls);
push @threads, async { $ua->get($url) };
}
...
}
通过使用工作者模型,您可以重用线程以避免启动它们所花费的时间。这也会按照您想要的顺序收集响应。
use threads;
use Thread::Queue 3.01 qw( );
my $request_q = Thread::Queue->new();
my $response_q = Thread::Queue->new();
my @threads;
push @threads, async {
my $ua = LWP::UserAgent->new();
while (my $url = $request_q->dequeue()) {
$response_q->enqueue([ $url, $ua->get($url) ]);
}
};
$request_q->enqueue($_) for @urls;
$request_q->end();
my %responses;
for my $url (@urls) {
while (!$responses{$url}) {
my ($response_url, $response) = @{ $response_q->dequeue() };
$responses{$response_url} = $response;
}
my $response = delete($responses{$url});
...
}
$_->join for @threads;