2

我是 perl 新手。目前我正在运行一个 perl 脚本,它将调用另一个 perl 脚本。第二个 perl 脚本有 2 个输入参数

sample2.pl -itest.txt -ffile1.txt

我有不同的输入参数-flike file1,file2,file3...file10

现在我想为当前运行的所有输入参数(file1、file2、file3)并行运行第二个 perl 脚本 -

#!/usr/bin/perl
use warnings;

use strict;

my $fi="output3.txt";--(output3.txt will contain the files file1,file2..file10)
    open (OF, $fi);

foreach(<OF>)
{
system ("perl ucm3.pl -iinput.txt -f$_ ");

print $_;
}

但它不是并行运行的,而是一个接一个地运行。请帮助并行运行这些脚本。提前致谢。

4

5 回答 5

6

您需要创建一个新进程并将其与主程序分离。您可以使用 步行执行此操作fork但您也可以使用Parallel::ForkManager执行此操作。它会为你处理一切。

use strict; use warnings;
use Parallel::ForkManager;

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

open (my $fh, '<', "output3.txt") or die $!;
while (my $data = <$fh>) {
  chomp $data;

  # Forks and returns the pid for the child:
  my $pid = $pm->start and next;

  # we are now in the child process
  print system ("perl ucm3.pl -iinput.txt -f$data ");

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

编辑:如果您还不熟悉 Perl,请查看本手册。它将告诉您如何从 CPAN 获取 Parallel::FormManager (和其他东西)。

于 2013-01-29T15:00:34.410 回答
1

除了给出的其他好的答案之外,您还应该考虑重新设计,这样您就不会使用system每个进程来启动一个新的 Perl 实例。

启动所有这些perls 将增加开销(如果您试图通过并行处理加快速度,这可能是您关心的事情)。

理想情况下,您会将 ucm3.pl 制作成可以从主程序调用的模块。

但是对于快速破解解决方案,您可以将整个文件包装在一个子例程调用中:

sub ucm3
{
    #a trick to make the sub arguments look like program arguments.
    local @ARGV = @_;

    [ rest of the ucm3.pl file in here. ]

}

现在,在您的程序中,包含该文件:

require 'ucm3.pl';

而不是你的系统调用,你可以这样做:

ucm3("-iinput.txt", "-f$_");

结合forkthreads按照其他答案中的建议。

更新:由于您每次都使用相同的“input.txt”文件,您可以通过重构代码来进一步提高效率,以便“input.txt”只处理一次。如果该文件很大,则尤其如此。

于 2013-01-29T15:46:14.013 回答
0

对于并行处理,您可以使用threads. 可以在此处研究文档。

于 2013-01-29T14:59:28.527 回答
0

如果您正在使用类似 Unix 的系统,您将能够进行系统调用,在系统命令的末尾放置一个 & :

system "perl ucm3.pl -iinput.txt -f$_ &"
于 2013-01-29T15:10:06.777 回答
0

您也可以使用线程和 Thread::Queue 来执行此操作。它比 Parallel::ForkManager 稍微冗长一些,但它易于管理,并且可以轻松修改以捕获所有输出并将它们传递到另一个队列。

#!/usr/bin/env perl

use warnings;
use strict;

use threads;
use Thread::Queue;
use contant MAX_THREADS => 10;

# create a queue that we will fill with work
my $q = Thread::Queue->new();

open (my $fh, '<', "output3.txt") or die "cannot open output3.txt $!";
while (my $data = <$fh>) {
  chomp $data;
  # add each file to the queue
  $q->enqueue($data);
}

for (1..MAX_THREADS) {
  # create some faux signals to end work
  $q->enqueue("SIGEXIT");
  # create threads and do work
  threads->create("work");
}

# wait until threads are all done
while (threads->list(threads::running)) {
  sleep 1;
}
print "all done\n";

# subroutine each thread performs
sub work {
  while (my $file = $q->dequeue()) {
    last if $file eq 'SIGEXIT';
    print system ("perl ucm3.pl -iinput.txt -f$file");
  }
  # detach thread for automatic cleanup
  threads->detach;
}
于 2013-01-29T15:47:58.123 回答