我正在使用perl的threads模块,它带有一个简单的搜寻器,我正在开发,因此我可以并行下载页面。 Ocasionally,我得到错误信息像这样的:perl线程异常退出
Thread 7 terminated abnormally: read timeout at /usr/lib64/perl5/threads.pm line 101.
Thread 15 terminated abnormally: Can't connect to burgundywinecompany.com:80 (connect: timeout) at /usr/lib64/perl5/threads.pm line 101.
Thread 19 terminated abnormally: write failed: Connection reset by peer at /usr/lib64/perl5/threads.pm line 101.
当我线性运行该脚本无绪,我不会遇到这些错误。这些错误几乎看起来像是来自LWP::UserAgent模块,但他们似乎不应该导致线程异常退出。使用perl的线程时是否需要采取一些额外的预防措施?谢谢!
UPDATE:
我已经找到了这些异常终止的来源,它似乎是,每当我做使用LWP::UserAgent
的请求。如果我删除方法调用来下载网页,则错误将停止。
示例脚本
下面的脚本会导致一个错误,我说的。最后浏览的网址就会超时,导致什么应该仅仅是HTTP :: Repsonse对象的一部分,而不是导致线程异常终止:
#!/usr/bin/perl
use threads;
use Thread::Queue;
use LWP::UserAgent;
my $THREADS=10; # Number of threads
#(if you care about them)
my $workq = Thread::Queue->new(); # Work to do
my @stufftodo = qw(http://www.collectorsarmoury.com/ http://burgundywinecompany.com/ http://beetreeminiatures.com/);
$workq->enqueue(@stufftodo); # Queue up some work to do
$workq->enqueue("EXIT") for(1..$THREADS); # And tell them when
threads->create("Handle_Work") for(1..$THREADS); # Spawn our workers
$_->join for threads->list;
sub Handle_Work {
while(my $todo=$workq->dequeue()) {
last if $todo eq 'EXIT'; # All done
print "$todo\n";
my $ua = LWP::UserAgent->new;
my $RESP = $ua->get($todo);
}
threads->exit(0);
}
您是否确保为每个线程获取所有内容的新实例?审核代码以确保每个线程中都没有共享,每个线程都需要初始化自己的perl对象,很少应该传入(比如只有URL),并且不应该访问共享的全局变量。我怀疑这个问题只是设计错误。 –
@DarrylMiles,我已经发布了上面的示例脚本,导致错误。我很确定在这个脚本文件中没有共享任何东西,但我仍然得到错误。 – srchulo
好的脚本至少我们可以看到你在做什么。你只有4个项目放置在$ workq中,但是你启动了10个线程,每个线程可以在多个项目上工作。第四个线程不可能看到任何工作要做。目标网站是由您拥有/管理的吗?你怎么知道他们没有连接泛滥控制?原始错误中的线程编号指示超过10个(如果它们是连续的)。可以将子线程添加到当前线程启动开始/停止以及所有工作的总数中,也会在所有输出中发出threads-> tid()。也许你更好地看问题。 –