2

我正在使用以下子例程运行 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();
}
4

1 回答 1

4

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

您的代码在 5.10.1 中运行良好,并且 HTTP::Lite 可能只是无法解决您遇到的任何 perl 错误。您可能只需要使用更新版本的 Perl。您获得的越老和越接近 Redhat,线程就越不稳定。如果您打算使用线程,请使用最新的 Perl。

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

于 2009-12-05T09:16:15.050 回答