質問

次のサブルーチンで 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();
}
役に立ちましたか?

解決

非スレッドセーフの純粋な Perl コードはセグメンテーション違反を引き起こしません (実際、純粋な Perl コードはセグメンテーション違反を引き起こすべきではありません)。Perl のバグによりセグメンテーション違反が発生します。Perl のスレッドは歴史的に非常にバグが多かったですが、現在はかなり改善されています。

あなたのコードは 5.10.1 で正常に動作し、HTTP::Lite はおそらくあなたが遭遇した Perl のバグを気にしません。おそらく、新しいバージョンの Perl を使用する必要があるだけです。古くて Redhat に近づくほど、スレッドの安定性は低くなります。スレッドを使用する場合は、入手できる最新の Perl を使用してください。

スレッドの代わりに、次のようなものを使用できます Parallel::ForkManager, LWP::パラレル あるいは驚くべきことさえ フォーク フォークを使用してスレッドをエミュレートするモジュール。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top