【问题标题】:Is LWP::UserAgent not thread-safe?LWP::UserAgent 不是线程安全的吗?
【发布时间】:2009-12-03 23:50:31
【问题描述】:

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

【问题讨论】:

  • 我会检查 Digest::MD5。每次我使用它时,我都会将它包装在一个 eval 中。
  • 我确实在没有它的情况下测试了脚本,并以相同的速率结束了核心转储。
  • 您没有在线程中使用 Thread::Pool 是吗?似乎有一些共识认为该模块可能会导致问题。
  • 从一个完整的测试程序中尽可能多地删除,仍然有问题,并展示给我们?
  • 除非你展示一个完整的例子,包括你如何使用线程,否则没有人可以帮助你。

标签: perl multithreading thread-safety lwp-useragent


【解决方案1】:

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

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

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

【讨论】:

  • Redhat 会导致线程出错怎么办?确实,我正在开发 CentOS 机器。
  • 他们因修补 Perl、将实验性补丁投入稳定版本、搞砸事情然后不发布修复程序而臭名昭著。它在早期的 5.8 中变得特别糟糕,当时他们相当努力地破坏了 Unicode,然后将默认设置为 UTF-8。情况可能有所改善,我对任何 Perl rpm 都保持警惕。
猜你喜欢
  • 2011-09-24
  • 2014-02-07
  • 2010-10-15
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 2021-10-12
  • 2015-04-18
  • 2011-10-07
相关资源
最近更新 更多