我正在使用谷歌来解释我的问题 我在谷歌上计算了搜索请求的延迟时间,我正在打印它 现在,我需要最大时间,最短时间,平均时间等数据。所以我试图将数据推送到可以在以后操作的数组。 数组出来是空白的。似乎这是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";
}
答案 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;
}