2015-03-02 51 views
0

我想從一個Perl腳本調用多個Perl實例/腳本。請參閱簡單的腳本,低於該說明problme很好通過Perl系統函數調用多線程

my @filenames = {"file1.xml","file2.xml","file3.xml",file4.xml"} 
foreach my $file (@filenames) 
{ 
    #Scripts which parses the XML file 
    system("perl parse.pl $file"); 

    #Go-On don't wait till parse.pl has finished 

} 

由於我是一個四核CPU和單個文件的解析上需要一段時間,我想拆作業。有人能指出我的方向嗎?

感謝和最誠摯, 添

+2

並行:: ForkManager – ikegami 2015-03-02 11:55:02

+1

'系統(「perl的parse.pl $文件&");' 比照http://stackoverflow.com/questions/2711520/how-can-i-run-perl-system - 命令在這個背景 – 2015-03-02 12:09:10

+0

「背景」,這是我的首字母搜索一詞缺失 - 非常感謝 – 2015-03-02 12:28:01

回答

1

以多核心的優勢隱含並行工作負載有很多方法可以做到這一點。

最明顯的是 - 系統調用後綴爲後綴,並且它會關閉並在後臺執行。

my @filenames = ("file1.xml","file2.xml","file3.xml",file4.xml"); 
foreach my $file (@filenames) 
{ 
    #Scripts which parses the XML file 
    system("perl parse.pl $file &"); 

    #Go-On don't wait till parse.pl has finished 

} 

這很簡單,但應該做的伎倆。這種方法的缺點是不能很好地擴展 - 如果你有很長的文件列表(比如說1000),那麼它們都會立即啓動,並且你可能會耗盡系統資源並導致問題。

所以,如果你想要一個更受控制的方法 - 你可以使用分叉或線程。 fork ing使用C系統調用,並啓動重複的流程實例。

use Parallel::ForkManager; 
my $manager = Parallel::ForkManager -> new (4); #number of CPUs 
my @filenames = ("file1.xml","file2.xml","file3.xml",file4.xml"); 
foreach my $file (@filenames) 
{ 
    #Scripts which parses the XML file 
    $manager -> start and next; 
    exec("perl", "parse.pl", $file) or die "exec: $!"; 
    $manager -> finish; 

    #Go-On don't wait till parse.pl has finished 

} 

# and if you want to wait: 
$manager -> wait_all_children(); 

如果你想要做的事,涉及捕獲輸出和後處理它,我會在threadsThread::Queue方面暗示思維。但是如果不需要同步,這是不必要的。

(如果你想這可能是有用的,我將提供: Perl daemonize with child daemons

編輯:修訂後的基礎上的意見。池上正確地指出:

system(「perl parse.pl $ file」); $管理器 - >完成;是浪費(每個工人三個進程)。使用:exec(「perl」,「parse.pl」,$ file)或者死掉「exec:$!」; (每個工人一個進程)。

+2

'system(「perl parse.pl $ file」); $ manager-> finish;'是浪費(三每個工作者的進程)使用:exec(「perl」,「parse.pl」,$ file)或者死掉「exec:$!」;'(每個工作者一個進程)。 – ikegami 2015-03-02 12:54:52