如何从子处理1000s的文件中分出有限的后台进程

时间:2014-09-24 14:09:37

标签: perl fork

我只想在后台打开一个压缩/未压缩的文件,并根据压缩文件上的处理生成一个新文件。

我可以用Parallel::ForkManager来做,但我相信这不可用。

我发现了这个,但我不确定如何使用它:

sub backgroundProcess {
    my $file = shift;
    my $pid  = fork;
    return if $pid;    # in the parent process
    &process_file($file);
    exit;              # end child process
}

sub process_file {
    my $file    = shift;
    my $outFile = $file . ".out";
    # ...here...
    open( readHandle,  "<", $file )    or die print "failed $!";
    open( writeHandle, ">", $outFile ) or die "failed write $!";
    # some processing here.....
    # and then closing handles...
}

循环:

foreach my $file (@filesToProcess) {
    &backgroundProcess($file);
}

我的问题:

  1. 即使backgroundProcess发生后,return中创建的子流程也会运行(在return if $pid行?
  2. process_file中,如何确保为每个文件打开一个唯一的文件句柄,或者“fork”处理它?<​​/ li>
  3. 在循环中(通过@filesToProcess),我想一次只运行 一定数量的进程,那么如何检查后台进程的数量是否等于$LIMIT,然后打开一个旧的完成?

2 个答案:

答案 0 :(得分:3)

如果我理解了您问题的标题,那么您正在寻找Parallel::ForkManager

我不明白为什么Parallel::ForkManager不可用。它是一个纯粹的Perl模块。

use Parallel::ForkManager;

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

for my $file (@filesToProcess) {
  # Forks and returns the pid for the child:
  my $pid = $pm->start and next;

  ... do some work with $data in the child process ...

  $pm->finish; # Terminates the child process
}

您只需将模块的.pm文件复制到您可以找到的位置即可。例如:

/some/custom/path/myscript
/some/custom/path/inc/Parallel/Forkmanager.pm

然后,在myscript

use FindBin qw( $RealBin );
use lib "$RealBin/inc";
use Parallel::ForkManager;

当然,如果由于某种不可思议的原因你无法做到这一点,你可以随时fatpack编写脚本。

答案 1 :(得分:0)

Re Q1:是的。只有父进程才会执行返回,因为子进程中$ pid将为零。

问题Q2:不确定我是否正确理解了您的问题。 open()将在子进程中执行,因此文件句柄将是子进程的本地句柄。

问Q3:您必须手动跟踪。达到限制后,调用wait()等待一个孩子退出,然后再开始新的子进程。见http://perldoc.perl.org/functions/wait.html