如何从perl

时间:2015-07-21 07:42:06

标签: perl

我正在使用谷歌来解释我的问题 我在谷歌上计算了搜索请求的延迟时间,我正在打印它 现在,我需要最大时间,最短时间,平均时间等数据。所以我试图将数据推送到可以在以后操作的数组。 数组出来是空白的。似乎这是parallel-forkmanager的限制。请提出一些建议。

我的代码:

use Parallel::ForkManager;
use WWW::Mechanize;
use LWP::UserAgent;
use Time::HiRes qw/gettimeofday/;
use Time::Format qw/%time/;
use POSIX       qw( strftime );
use Time::HiRes qw( gettimeofday );
$count=5;
@arr=();
$pm = new Parallel::ForkManager($count);   
for(1..$count)  
{     
  $pm->start and next;      
  $m = WWW::Mechanize->new();
  $m->get( "http://www.google.com" );
  $s1=gettimeofday;
  my ($secs, $microsecs) = gettimeofday();
  print strftime("%H:%M:%S", localtime($secs)) . sprintf(".%04d",

$microsecs/10);
  $m->submit_form(
  form_number => 1,
  fields    => {q=>'abcd'},
  );

  print " ";
  print $m->title;
  print " ";
  $s2=gettimeofday;
  my ($secs, $microsecs) = gettimeofday();
  print strftime("%H:%M:%S", localtime($secs)) . sprintf(".%04d",   

$microsecs/10);
  $s3=$s2-$s1;
  $s3=$s3*1000;
  print "  $s3\n";
  push(@arr,$s3);
  $pm->finish   }  

$pm->wait_all_children; ## wait for the child processes
foreach(@arr)
{
print "$_\n";
}

2 个答案:

答案 0 :(得分:4)

您需要将run_on_finish callback添加到管理器实例,然后使用2个参数调用finish method。因此,您可以将finish调用的第二个参数作为run_on_finish回调的第六个参数。

# parent
my @arr;
$pm->run_on_finish(sub {
    push(@arr, ${$_[5]});
});

# child
my $val = 42;
$pm->finish(0, \$val);

# parent
$pm->wait_all_children();
print($_, "\n") for @arr;

答案 1 :(得分:2)

并不是Parallel::ForkManager作为并行代码的一般限制的限制。 fork会生成一个新进程,该进程是现有进程的副本。它拥有自己的内存空间,任何在孩子和父母之间发生变化的事情都是......好吧,改变了。

线程有很多相同的问题。

关于如何使用进程间通信有一个很大的篇章 - perlipc

Parallel::ForkManager特别有几种将数据返回到父进程的机制。就个人而言 - 我并不真正相处,因为虽然它有效,但它也试图成为问题的一般解决方案。

我会考虑使用管道将信息传回父进程。

use strict;
use warnings;
use Data::Dumper;

use Parallel::ForkManager;
use IO::Pipe;

my $pm = Parallel::ForkManager->new(2);

for ( 1 .. 4 ) {
    my $pipe = IO::Pipe->new();
    my $pid  = $pm->start;
    if ($pid) {

        #parent
        $pipe->reader->autoflush;
        while (<$pipe>) {
            print "Got data from $pid: $_\n";
        }
        close ( $pipe );
    }
    else {
        #is child
        $pipe->writer->autoflush;
        print {$pipe} "Child $$ says hello!";
        close($pipe);
        print "Child $$ exiting\n";
    }
    $pm->finish;
}