2010-03-11 150 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