通过perl系统函数调用多个线程

时间:2015-03-02 11:40:34

标签: multithreading perl system

我想从一个perl脚本调用多个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上并且解析单个文件需要一段时间,我想拆分作业。有人能指出我的方向吗?

谢谢,最好的, 添

1 个答案:

答案 0 :(得分: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使用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)或die" exec:$!&#34 ;; (每个工人一个过程)。