Является ли LWP :: UserAgent потокобезопасным? - PullRequest
2 голосов
/ 04 декабря 2009

Я использую 40 или около того потоков со следующей подпрограммой:

my $app = shift;
my $ua = LWP::UserAgent->new();
$ua->timeout(5);
my $response = $ua->get($$app{'watch_url'});
my $new_md5;
if ($response->is_success()) {
    $new_md5 = md5_hex($response->content());
}
return ($$app{'short_name'}, $$app{'watch_md5'}, $new_md5);

Основные выбросы происходят примерно в 3/4 времени. LWP и LWP :: UserAgent - чистый Perl, поэтому я застигнут врасплох этим. Является ли LWP :: UserAgent потокобезопасным?

Обновление:

Вот минимальная версия, чтобы воспроизвести проблему:

use strict;
use warnings;
use threads;
use LWP::UserAgent;

sub check_app {
    my $ua = LWP::UserAgent->new();
    $ua->timeout(5);
    $ua->get('http://www.flatdoc.com/?' . rand(10));
}

my @threads;
for (my $i = 0; $i < 40; $i++) {
    my $thread = threads->create(\&check_app);
    push(@threads, $thread);
}
foreach (@threads) {
    $_->join();
}

1 Ответ

4 голосов
/ 05 декабря 2009

Не-потокобезопасный чистый Perl-код не вызывает segfault (фактически, ни один чистый Perl-код не должен вызывать segfault). Ошибка в Perl вызывает segfault. И потоки в Perl исторически очень глючные, но они стали намного лучше.

Ваш код отлично работает в 5.10.1, и HTTP :: Lite, вероятно, просто не справляется с любой ошибкой perl, с которой вы столкнулись. Скорее всего, вам просто нужно использовать более новую версию Perl. Чем старше и ближе к Redhat вы получаете, тем менее стабильные темы. Если вы собираетесь использовать потоки, используйте новейший Perl, который вы можете получить.

В качестве альтернативы потокам вы можете использовать что-то вроде Parallel :: ForkManager , LWP :: Parallel или даже удивительный модуль forks , который эмулирует потоки используя вилку.

...