2010-03-11 42 views
2

我有一个使用Parallel::ForkManager的脚本。但是,即使在所有子进程完成之后,wait_all_children()进程也需要很长时间。我知道的方法是打印出一些时间戳(见下文)。有没有人有任何想法可能会导致这种情况(我的机器上有16个CPU核心)?Perl Parallel :: ForkManager wait_all_children()需要很长时间

my $pm = Parallel::ForkManager->new(16); 
for my $i (1..16) { 
    $pm->start($i) and next; 

    ... do something within the child-process ... 

    print (scalar localtime), " Process $i completed.\n"; 
    $pm->finish(); 
} 
print (scalar localtime), " Waiting for some child process to finish.\n"; 
$pm->wait_all_children(); 
print (scalar localtime), " All processes finished.\n"; 

很显然,我会先拿到Waiting for some child process to finish消息,有,比方说,7:08:35时间戳。然后我会得到一个Process i completed消息的列表,最后一个在7:10:30。但是,我没有收到All Processes finished的消息,直到7:16:33(!)。为什么7点到10点和7点16分33秒之间有6分钟的延迟?谢谢!

+0

这是你正在运行的代码?有一个不那么微妙的语法错误。 – 2010-03-11 21:42:44

+0

更正了该错误。 – Zhang18 2010-05-21 14:49:18

回答

8

我尝试这样做:

#!/opt/perl/bin/perl 

use strict; use warnings; 

use Parallel::ForkManager; 

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

for my $i (1..16) { 
    $pm->start($i) and next; 
    sleep rand 20; 
    printf "%s : Process %d completed\n", scalar localtime, $i; 
    $pm->finish; 
} 

printf "%s: Waiting for some child to finish\n", scalar localtime; 
$pm->wait_all_children; 

printf "%s: All processes finished.\n", scalar localtime; 

我:

[[email protected] Src]$ ./y.pl 
Thu Mar 11 17:14:16 2010 : Process 3 completed 
Thu Mar 11 17:14:16 2010: Waiting for some child to finish 
Thu Mar 11 17:14:18 2010 : Process 8 completed 
Thu Mar 11 17:14:18 2010 : Process 14 completed 
<snip>...</snip> 
Thu Mar 11 17:14:34 2010 : Process 12 completed 
Thu Mar 11 17:14:34 2010: All processes finished.

perl 5.10.1的Linux上0.7.5Parallel::ForkManager版本。

因此,我的结论是什么问题您有正在发生的事情是会发生什么后果,当你

# ... do something within the child-process ... 

更新:的问题是,你是在finish调用之前打印Process finished message。请尝试以下版本:

#!/opt/perl/bin/perl 

use strict; use warnings; 

use Parallel::ForkManager; 

my $pm = Parallel::ForkManager->new(16); 
$pm->run_on_finish(sub { 
    printf "%s : Process completed: @_\n", scalar localtime 
}); 

for my $i (1..16) { 
    $pm->start($i) and next; 
    sleep rand 20; 
    $pm->finish; 
} 

printf "%s: Waiting for some child to finish\n", scalar localtime; 
$pm->wait_all_children; 

printf "%s: All processes finished.\n", scalar localtime; 

请参阅Callbacks in Parallel::ForkManager documentation了解更多信息。如果延迟消失,那么您观察到的症状是由于您声称分叉过程在完成之前已完成。

+0

你说得对,思南。我忘了提及这种延迟不会发生在我身上。只有当我的每个子进程需要很长时间并且有很多系统资源完成时才会发生。然而,困扰我的是,无论孩子发生什么,在打印上一个“我完成的过程”之后,都不应再相关。但这里是我得到的实际输出: 08:02:43:等待一些孩子... 08:06:00:组1完成。 ... 08:06:12:第16组完成。 08:07:03:全部完成。 我想知道如果我应该明确地释放一些阻塞等待的内存/资源? – Zhang18 2010-03-12 14:05:16

+0

@ Zhang18使用'run_on_finish'回调查看我的更新回答。 – 2010-03-12 14:51:39

+0

我明白了。所以如果我通过run_on_finish()打印时间戳,我会得到你所期望的(即,由于wait_for_children没有额外的等待时间)。然而,我的问题因此变成了为什么儿童过程不被分叉视为“完成”,即使我已经在循环内部达到了该打印语句?可以肯定的是,我对循环内的任务没有任何幻想。这只是一些算术计算加上一些数据库查询和文件I/O。延迟似乎是由于$ pm-> finish()方法未能提取子进程的实际结束时间而造成的。 – Zhang18 2010-03-12 18:41:57