2

異なるプラットフォームでいくつかの子プロセスを並行して実行しようとしています。親プロセスは、すべての子プロセスがそれぞれのプラットフォームで完了した後にのみ続行する必要があります。

問題は、フォークを使用して子プロセスで「exec」コマンドを実行すると、ほぼ瞬時に終了することです。また、出力に一貫性がありません。ほとんどの場合、ログには 1 行しか表示されません。

-bash-2.05b$ cat Agent.SOLSPARC
caught SIGTERM signal, cleaning up

また

-bash-2.05b$ cat Agent.SOLSPARC
Host: EBSO9SPC  Login: esm2 

場合によっては、余分な行がいくつかあり、最後に「シグナル 15 によって強制終了されました」というメッセージが表示されます。「exec」で使用するコマンドは、実際にはリモートボックスに接続してmakeコマンドを実行するスクリプトを呼び出します。テスト目的で、私は現在、SOLSPARC という 1 つのプラットフォームのみを渡しています。また、特定のプラットフォームでコマンドが終了したかどうかを知りたいだけです。

すべての引数を「exec」に正しく渡しているかどうかわからなかったので、(インターネット上のさまざまなリンクを参照した後) さまざまな組み合わせを試しましたが、役に立ちませんでした。重要な観察事項の 1 つは、strace を使用してこの問題をデバッグしたところ、コマンドが正常に機能したことです。Perldoc で、Unix プラットフォームでは exec が/bin/sh -cを使用しているのを見ましたが、他のプラットフォームでは異なります。exec と strace が異なるシェルを使用していることですか?

私のコードの関連部分は次のとおりです。

sub compile {
    my %child_pids;
    foreach $plat (0 .. $#plat_list) {
        my $pid = fork;
        # Didn't check the undef condition for child
        if ($plat_list[$plat] eq "SOLSPARC") {
            print "\nStarted Solaris build \n";
            if ($pid == 0) {
                print "Inside Child Process \n\n";
                exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_US distclean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";
            } elsif ($pid > 0) {
                $child_pids{"SOLSPARC"} = $pid;
            }
        } else {
           print "\nStarted build for other platforms \n";
           if ($pid == 0) {
                print "Inside Child Process \n\n";
                exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_GB clean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";     
           } elsif ($pid > 0) {
                $child_pids{"$plat_list[$plat]"} = $pid;
           }
        }
    }


    my %rev_child_pids = reverse %child_pids;
    while ((my $kid = waitpid -1, WNOHANG) > 0) {
        if ($rev_child_pids{$kid} eq "SOLSPARC") {
            print "\nChild process completed for SOLARIS platform $rev_child_pids{$kid} \n";
            print "Run some other command here \n";
        } else {
            print "\nChild process completed for other platform $rev_child_pids{$kid} \n";
            print "No more commands to run \n";
        }
    }
}

助言がありますか?

4

1 に答える 1

0

「exec」の代わりに「system」を使用してみてください。

system `${ROOT}/${REM_EXEC} -t 1200 -c "make LANG=en_US distclean " -b ${ROOT} -l Agent. $plat_list[$plat]` 

「システム」は fork との関係で動作が少し異なるため、問題が解決する可能性があります。

于 2013-04-18T17:43:50.710 に答える