2

私はperlが初めてです。現在、別の perl スクリプトを呼び出す perl スクリプトを実行しています。2 番目の perl スクリプトには 2 つの入力パラメータがあります

sample2.pl -itest.txt -ffile1.txt

-flikeにはさまざまな入力パラメーターがありますfile1,file2,file3...file10

今、私は現在実行中のすべての入力パラメータ(ファイル1、ファイル2、ファイル3)に対して2番目の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

新しいプロセスを作成し、メイン プログラムから切り離す必要があります。これは を使用して徒歩で実行できますが、 forkParallel::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」が 1 回だけ処理されるようにコードをリファクタリングすることで、さらに効率が向上する可能性があります。これは、そのファイルが大きい場合に特に当てはまります。

于 2013-01-29T15:46:14.013 に答える
0

Unixライクなシステムで作業している場合は、システムコマンドの最後に&を配置してシステムコールを実行できます。

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

並列処理には、 を使用できますthreadsドキュメンテーションはここで学ぶことができます。

于 2013-01-29T14:59:28.527 に答える
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 に答える