LWP :: UserAgent不是线程安全的吗?

时间:2009-12-03 23:50:32

标签: perl multithreading thread-safety lwp-useragent

我正在使用以下子程序运行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 个答案:

答案 0 :(得分:4)

非线程安全的纯Perl代码不会导致段错误(实际上,没有纯Perl代码会导致段错误)。 Perl中的错误会导致段错误。而Perl中的线程在历史上非常错误,但它们已经变得更好了。

你的代码在5.10.1中运行正常,HTTP :: Lite可能只是不会碰到你遇到的任何perl bug。可能你只需要使用更新版本的Perl。越老越接近Redhat,线程越不稳定。如果您打算使用线程,请使用最新的Perl,您可以开始使用它。

作为线程的替代方法,您可以使用Parallel::ForkManagerLWP::Parallel甚至是使用fork模拟线程的惊人forks模块。