这是我的代码:
use LWP;
use threads;
use strict;
use warnings;
my @thrds;
for (1..100)
{
push @thrds, threads->create( 'doit' );
}
for (@thrds)
{
$_->join();
}
sub doit
{
LWP::UserAgent->new->get("http://dx.doi.org/10.1002/aoc.1067");
}
我使用的是Windows 7 x64和ActivePerl 5.20.2 x64,我也试过了StrawberryPerl。 我有很多错误:
线程...异常终止:无法定位对象方法" _uric_escape"通过包" URI"在... / URI.pm第81行
字符串找到运算符预期在(eval 10)第8行,接近" croak'用法:$ io-> getlines()'"
(你需要预先宣布呱呱叫吗?)
如果我添加
sleep 1;
前
push @thrds, threads->create( 'doit' );
它没关系。
问题是什么?
答案 0 :(得分:2)
我不确定原因,但处理动态加载的模块似乎存在问题。在创建线程之前显式加载它们可以解决问题。换句话说,添加以下内容:
use Carp qw( );
use URI qw( );
答案 1 :(得分:1)
我认为这里的问题将是内存占用。毕竟,您正在加载LWP
库,然后将您的流程克隆100次。
与流行的看法相反,perl中的线程甚至不是远程轻量级的。它们不适合这种使用模式 - 每个线程都是您的流程的“完整副本”,而这只是......不是一个好的计划。
我的perl副本 - ActivePerl 5.20.2 - 没有出现同样的问题(我不认为 - 我实际上并不想垃圾邮件列出你所列的网站)。
我建议您改写使用Thread::Queue
的线程和较低程度的并行度:
use strict;
use warnings;
use LWP;
use threads;
use Thread::Queue;
my $workers = 10;
my $work_q = Thread::Queue->new();
my $url = "http://localhost:80";
sub worker_thread {
while ( my $url = $work_q->dequeue ) {
LWP::UserAgent->new->get($url);
}
}
threads->create( \&worker_thread ) for 1 .. $workers;
for ( 1 .. 100 ) {
$work_q->enqueue($url);
}
$work_q->end;
foreach my $thread ( threads->list ) {
$thread->join();
}
否则,基于fork的方法也可能更好:
use strict;
use warnings;
use Parallel::ForkManager;
use LWP;
my $manager = Parallel::ForkManager->new(10);
for ( 1 .. 100 ) {
$manager->start and next;
LWP::UserAgent->new->get("http://localhost:80");
$manager->finish;
}
$manager->wait_all_children;
编辑:
对您的示例进行更多测试 - 我在运行5.20.2
的RHEL上遇到类似的运行时错误它们有所不同,这确实意味着必须有某种竞争条件在这里发生。
这很奇怪,因为线程假设是独立的而它们不是。
特别是 - 我的内核炸弹由于内存耗尽导致内存耗尽而导致'杀死',这是不使用此方法的一个很好的理由。
我使用RHEL和Perl 5.20.2运行代码的测试用例也会引发问题(偶尔)。
我得到的是类似的错误 - 偶尔。我看不出明显的消息来源。它可能就像打开文件描述符太多或消耗太多内存一样简单。这是一个非常沉重的记忆负担。
答案 2 :(得分:0)
使用 Mojolicious 框架非常简单。 Mojo::UserAgent
类设计为在Mojo::IOLoop
模块的帮助下异步工作,虽然同步事务可用但它们是使用标准异步调用的特殊情况实现的
<div id="small-img" class="text-center col-xs-12 col-sm-12 col-md-12 col-lg-12 pagination-centered footer-bottom-img">
<ul >
<li>
<img class="img-responsive inline-block center-block" alt="" src="ssl_secure.png">
</li>
<li>
<img class="img-responsive inline-block center-block" alt="" src="secure-cc-paypal.png">
</li>
<li>
<img class="img-responsive inline-block center-block" alt="" src="gt-secured-seal.gif">
</li>
</ul>
</div>
快速基准测试给出了以下结果
答案 3 :(得分:0)
我知道这是一个古老的话题,但就在昨天我遇到了这个问题。以下信息对某人有用。 我在类似代码(并行http请求)中从LWP获得了几种错误,包括
在添加以下行后问题似乎消失了:
use IO::File;
不要问我为什么,我不知道:)意外地想出来了。 我正在使用Strawberry Perl 5.24.0。