我编写了一个 Perl 脚本,使用WWW::Mechanize
它从文本文件中读取 URL 并一一连接到它们。在每个操作中,它都会解析网页的内容,寻找一些特定的关键字,如果找到,则会将其写入输出文件。
为了加快这个过程,我使用Parallel::ForkManager
了MAX_CHILDREN
set to 3
。虽然我观察到速度有所提高,但问题是,一段时间后脚本崩溃了。Perl.exe
进程被杀死并且它不显示任何特定的错误消息。
我已经多次运行该脚本以查看它是否总是在同一点失败,但是失败点似乎是间歇性的。
请注意,我已经处理了任何内存泄漏,WWW::Mechanize
如下HTML::TreeBuilder::XPath
所示:
- 对于
WWW::Mechanize
,我设置stack_depth(0)
它不缓存访问页面的历史记录。 HTML::TreeBuilder::XPath
,完成后我删除根节点。这种方法帮助我解决了另一个类似脚本中的内存泄漏问题,该脚本不使用fork
.
这是脚本的结构,我这里只提到了相关部分,如果需要更多细节来解决问题,请告诉我:
#! /usr/bin/perl
use HTML::TreeBuilder::XPath;
use WWW::Mechanize;
use warnings;
use diagnostics;
use constant MAX_CHILDREN => 3;
open(INPUT,"<",$input) || die("Couldn't read from the file, $input with error: $!\n");
open(OUTPUT, ">>", $output) || die("Couldn't open the file, $output with error: $!\n");
$pm = Parallel::ForkManager->new(MAX_CHILDREN);
$mech=WWW::Mechanize->new();
$mech->stack_depth(0);
while(<INPUT>)
{
chomp $_;
$url=$_;
$pm->start() and next;
$mech->get($url);
if($mech->success)
{
$tree=HTML::TreeBuilder::XPath->new();
$tree->parse($mech->content);
# do some processing here on the content and print the results to OUTPUT file
# once done then delete the root node
$tree->delete();
}
$pm->finish();
print "Child Processing finished\n"; # it never reaches this point!
}
$pm->wait_all_children;
我想知道,为什么这个 Perl 脚本在一段时间后总是失败?为了便于理解,我在 fork manager 的完成方法之后添加了一个 print 语句,但是它没有打印出来。我也使用wait_all_children
了方法,因为根据 CPAN 上模块的文档,它将等待父进程的所有子进程的处理结束。
我不明白为什么wait_all_children
方法放在循环之外while
(for
如文档中所观察到的那样),因为所有处理都发生在循环内。
谢谢。