perl系统函数调用多线程

Invoke mutilple threads by perl system function

我想从一个 perl 脚本调用多个 perl instances/scripts。请看下面的简单脚本,它很好地说明了问题

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,而且解析单个文件需要一段时间,所以我想拆分作业。有人能给我指出一个好的方向吗?

谢谢,最好的, 蒂姆

利用多核处理隐式并行工作负载有很多方法。

最明显的是 - 在您的系统调用后添加一个 & 后缀,它会在后台充电并执行。

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 个?),那么它们会同时启动,你可能会耗尽系统资源并导致问题.

因此,如果您想要一种更可控的方法 - 您可以使用分叉或线程。 forking 使用 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(); 

如果您想做一些涉及捕获输出和 post 处理它的事情,我建议您考虑 threadsThread::Queue。但如果不需要同步就没有必要了。

(如果您认为这可能有用,我会提供: Perl daemonize with child daemons)

编辑:根据评论进行了修改。池上正确地指出:

system("perl parse.pl $file"); $manager->finish; is wasteful (three processes per worker). Use: exec("perl", "parse.pl", $file) or die "exec: $!"; (one process per worker).