1

同じ目的で設計されたさまざまな言語 (Perl、Java、R) で記述されたプログラムをベンチマークおよび比較するためのスクリプトを開発しています。同時に 2 つのサブルーチンを実行する必要があります。1 つは Unix TOP コマンドを使用するため、もう 1 つはプログラムを実行するためです。Parallel::ForkManager を使用しようとしています。ここで、フォークに使用しているコードの一部:

sub parallelRun{

$commands[0]= sub{topExec};
$commands[1]= sub{masExec};

my $manager = new Parallel::ForkManager( 2 );

for($i=0; $i <= $#commands; $i++) {

        $pid = $manager-> start and next;
        push(@pid,$pid);
        $commands[$i]();
        $manager-> finish;

    } # For End

    $manager->wait_all_children;
    $manager-> finish($pid[0]);
    undef(@pid);

} # Sub End

topExec()終了したら(TOP の実行)終了する必要がありmasExec()ますが、TOP コマンドの後にスクリプトがハングしています。

おまけの質問: 実行されたプログラムのシステム pid を取得masExec()して TOP コマンドで追跡する方法はありますか? 現在、Unix Top コマンド (サブ topExec) のユーザーとコマンドの列から追跡しています。

言語エラーで申し訳ありません(どちらもネイティブではありません;))。

4

1 に答える 1

2

kill(TERM => $pid[0]);


ところで、なぜここで P::FM を使用しているのかわかりません。2 つの子を作成する必要さえありません。

use POSIX qw( _exit );

sub parallelRun {
    my $pid = fork();
    die if !defined($pid);

    if (!$pid) {
       topExec();
       _exit(0);
    }

    masExec();
    kill(TERM => $pid);
    waitpid($pid, 0);
 }

Perl に関するいくつかのヒント:

常に使用しますuse strict; use warnings;。手始めに、宣言されていない変数がたくさんあります。

  1. $commands[0]= sub{topExec};
    $commands[1]= sub{masExec};
    

    する必要があります

    my @commands = ( \&topExec, \&masExec );
    

    (配列を宣言し、不必要な匿名サブルーチンを作成しないでください。)

  2. for(my $i=0; $i <= $#commands; $i++) {
        ... $commands[$i] ...
    

    もっとシンプルにすべき

    for my $i (0..$#commands) {
        ... $commands[$i] ...
    

    あるいは

    for my $command (@commands) {
        ... $command ...
    
  3. undef(@pid);
    

    は完全に不要です。これは、適切に宣言されていないことの症状です@pid

于 2013-05-29T04:27:05.823 に答える