我只是将Perl作为第四语言学习。
我希望使用Parallel::ForkManager
来加速使用其成员来自文本文件的数组的foreach
循环。
基本上我正在测试一个.txt文件的URL,并希望这样做,以便它一次测试阵列的多个成员,而不是一次测试一个(在这个例子中一次五个)并且没有垃圾邮件相同的URL无意中执行它。
这样的事情能做到吗?
$limit = new Parallel::ForkManager(5);
foreach (@lines) {
$limit->start and next;
$lines = $_;
... do processing here ...
$limit->finish;
}
或者它是否相当于运行该循环5次制作一个小的多线程DoS脚本?
答案 0 :(得分:4)
文档中不太清楚,但
对start
的调用将在父进程中阻止,直到运行的子进程数少于指定的限制为止。然后它将在父项中返回(非零)子PID,在子项中返回零
子进程可以看到父进程中调用start
时的所有数据。数据可能是写时复制,因为孩子可能会对其进行修改,但更改不会反映在任何其他流程的工作空间中
$pm->start and next
成语可能看起来有点模糊。基本上,如果start
方法返回 true 值,它会跳过循环的其余部分。我更喜欢下面代码中的my $pid = $fm->start; next if $pid;
或if
构造。两者都做同样的事情,但我认为更清晰
我建议您尝试使用这个更简单的应用程序,该应用程序使用五个子线程的缓存来打印从零到九的数字。
use strict;
use warnings;
use Parallel::ForkManager;
STDOUT->autoflush;
my $fm = Parallel::ForkManager->new(5);
for my $i (0 .. 9) {
my $pid = $fm->start;
if ($pid == 0) {
print "$i\n";
sleep 2;
$fm->finish;
}
}
答案 1 :(得分:-1)
要进行测试,请使用安全的本地流程(如打印或写入),以避免发送垃圾邮件。这是我编写的使用fork管理器的程序的工作片段。
my $pm=new Parallel::ForkManager(20);
foreach $add (@adds){
$pm->start and next;
#if email is invalid move on
if (!defined(Email::Valid::Loose->address($add))){
writeaddr(*BADADDR, $add); #address is bad
$pm->finish;
}
#if email is valid get domain name
$is_valid = Email::Valid::Loose->address($add);
if ($is_valid =~ m/\@(.*)$/) {
$host = $1;
}
$is_valid="";
# perform dsn lookup to check domain
@mx=mx($resolver, $host);
if (@mx) {
writeaddr(*GOODADDR, $add); #address is good
}else{
writeaddr(*BADADDR, $add); #address is bad
}
$pm->finish;
}