我是perl的新手。目前我正在运行一个perl脚本,它将调用另一个perl脚本。第二个perl脚本有2个输入参数
sample2.pl -itest.txt -ffile1.txt
我有-f
的{{1}}的不同输入参数。
现在我想为所有输入参数(file1,file2,file3)并行运行第二个perl脚本 目前我正在运行 -
file1,file2,file3...file10
但它不是并行运行,而是一个接一个地运行。请帮助平行运行这些脚本。 提前致谢。
答案 0 :(得分:6)
您需要创建一个新进程并将其从主程序中分离出来。您可以徒步with 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,请查看this manual。它将告诉您如何从CPAN获取Parallel :: FormManager(和其他东西)。
答案 1 :(得分:1)
除了给出的其他好答案之外,您还应该考虑重新设计,这样就不会使用system
来为每个进程启动一个新的Perl实例。
启动所有这些perl
会增加开销(如果您尝试使用并行处理加速,那么这可能是您关心的事情。)
理想情况下,您可以将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$_");
与其他答案中建议的fork
或threads
结合使用。
更新:,因为您每次都使用相同的“input.txt”文件,您可以通过重构代码来进一步提高效率,以便“input.txt”仅处理一次。如果该文件很大,则尤其如此。
答案 2 :(得分:0)
对于并行处理,您可以使用threads
。
可以研究文档here。
答案 3 :(得分:0)
如果您正在使用类似Unix的系统,那么您可以进行系统调用,并放置一个&amp;在系统命令的末尾:
system "perl ucm3.pl -iinput.txt -f$_ &"
答案 4 :(得分:0)
您也可以使用threads和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;
}