在foreach循环中使用Parallel :: ForkManager

时间:2014-06-22 21:44:01

标签: arrays multithreading perl

我只是将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脚本?

2 个答案:

答案 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;
}