所以,基本上我有一个非常大的数组,我需要从中读取数据。我希望能够并行执行此操作;然而,当我尝试时,我惨遭失败。为了简单起见,假设我有一个包含 100 个元素的数组。我的想法是将数组分成 10 个相等的部分并尝试并行读取它们(10 个是任意的,但我不知道我可以一次运行多少个进程,而 10 个似乎足够低)。我需要根据每个分区的读数返回一个计算(新数据结构),但我没有修改原始数组中的任何内容。
我没有完全尝试上述方法,而是尝试了一些更简单的方法,但我做错了,因为它在任何容量下都不起作用。所以,然后我尝试简单地使用子进程来推送到一个数组。下面的代码Time::HiRes
用于查看使用分叉而不是不使用分叉来运行它的速度有多快,但我还没有到那个时候(当我有接近几百万个条目时,我将对其进行测试在我的数组中):
use strict;
use warnings;
use Time::HiRes;
print "Starting main program\n";
my %child;
my @array=();
my $counter=0;
my $start = Time::HiRes::time();
for (my $count = 1; $count <= 10; $count++)
{
my $pid = fork();
if ($pid)
{
$child{$pid}++;
}
elsif ($pid == 0)
{
addToArray(\$counter,\@array);
exit 0;
}
else
{
die "couldnt fork: $!\n";
}
}
while (keys %child)
{
my $pid = waitpid(-1,0);
delete $child{$pid};
}
my $stop = Time::HiRes::time();
my $duration = $stop-$start;
print "Time spent: $duration\n";
print "Size of array: ".scalar(@array)."\n";
print "End of main program\n";
sub addToArray
{
my $start=shift;
my $count=${$start};
${$start}+=10;
my $array=shift;
for (my $i=$count; $i<$count +10; $i++)
{
push @{$array}, $i;
}
print scalar(@{$array})."\n";
}
注意:我用 push 代替了${$array}[$i]=$i
,因为我意识到我$counter
实际上并没有更新,所以这永远不会与这段代码一起工作。
我认为这不起作用,因为孩子都是原始程序的副本,而我实际上从未在“原始程序”中的数组中添加任何内容。在那张纸条上,我很困惑。同样,我实际上试图解决的实际问题是如何分区我的数组(其中包含数据)并尝试并行读取它们并根据我的读数返回计算(注意:我不会修改原始数组),但如果我不知道如何真正让我$counter
更新,我将永远无法做到这一点。我也想知道如何让上面的代码做我想做的事情,但这是次要目标。
一旦我可以让我的计数器正确更新,是否有可能在更新之前启动另一个进程并且我实际上不会读取整个数组?如果是这样,我该如何解释?
请,任何帮助将不胜感激。我很沮丧/卡住了。我希望有一个简单的解决方法。提前致谢。
编辑:我尝试使用 Parallel::ForkManager,但无济于事:
#!/usr/local/roadm/bin/perl
use strict;
use warnings;
use Time::HiRes;
use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new(10);
for (my $count = 1; $count <= 10; $count++)
{
my $pid = $pm->start and next;
sub1(\$counter,\@array);
$pm->finish; # Terminates the child process
}
$pm->wait_all_children;
我没有包括其他无关的东西,请参阅上面缺少的代码/子...再次,我们将不胜感激。我对此很陌生,需要有人握住我的手。我也尝试用run_on_start
and做一些事情run_on_finish
,但他们也没有工作。