2

私は完全にJavaで書いた大きなシステムに取り組んでいます。しかし、ある時点で、C プログラムをプロセスとして実行し、ファイル システムを介して C プログラムと通信し、ファイル システムを介して C プログラムと通信し、プログラムが終了して結果を読み取るのを待っています。今のところ、これしかできません。API などを介してそれらをリンクする時間はありません。

結果を得るためにこのプロセスを 2 回呼び出す必要があるまで、これはうまくいきました。最初の呼び出しを行うと、問題なく動作します。ただし、2 回目の呼び出しでは、プロセスがハングします。スリープ状態で信号を待っているかどうかはわかりませんが、なぜそうするべきなのかわかりません。

呼び出しを行うメソッドは次のとおりです。

public synchronized boolean processCommand(List command) {
    try { 
        ProcessBuilder pb = new ProcessBuilder(command);
        Process p = pb.start();
        p.waitFor();
        p.destroy();
    } catch(Exception ex) { return false; } 
    return true; 
}

stdout や stdin と通信する必要はありません。プロセスを実行してそのジョブを完了する必要があるだけです。しかし、呼び出しプロセスがそれを待っているときにハングするのは、2回目に呼び出したときだけです! 私の呼び出しコードは、単にコマンド リストを作成し、このメソッドを別の Java オブジェクトから呼び出すだけです。

メソッド processCommand(List command) への両方の呼び出しは、C プログラムへの入力が小さい場合に正常に機能します。それは標準入力または標準出力に問題がありますか?

それは私を夢中にさせているだけです!誰かがこれについて洞察を持っていますか?私はあなたの賞賛に感謝します:)

アップデート:

@Grayが言及したことに基づく解決策は次のとおりです。

InputStream と、場合によっては ErrorStream を排出する必要があるだけです。

public synchronized boolean processCommand(List command) {
try { 
    ProcessBuilder pb = new ProcessBuilder(command);
    Process p = pb.start();
    handleStream(p.getInputStream);
    handleStream(p.getErrorStream);
    p.waitFor();
    p.destroy();
} catch(Exception ex) { return false; } 
return true; 

}

public void handleStream(InputStream input) { 
    try { 
        int c; 
        while( (c=input.read())!= -1) { //Anything }
    } catch(Exception ex) { }
}
4

1 に答える 1

1

ここで提案されている解決策に従ってみてください(元のリンクは利用できないようです。アーカイブされたバージョンはここにありますが、サンプル コードへの参照リンクはまだ元のサイトを指しています...)

この状況を処理する最善の方法は、waitFor を呼び出す直前にスレッドを開始し、適切な時間の経過後に現在のスレッドを中断することです。TimerTask はまさにこの種の状況向けに設計されており、waitFor はほとんどの場合、割り込みに非常に反応します。[例については、元のリンクをたどってください]。

[...]

Java 6 API は、「サブプロセスの出力ストリームをすぐに読み取らないと、サブプロセスがブロックされ、さ​​らにはデッドロックが発生する可能性がある」と明確に述べています。</p>

[...]

現在、この問題を処理するための安全な方法は、Process.getOutputSteam、Process.getInputStream、および Process.getErrorStream を通じて利用可能になった各ストリームで close を呼び出して、Process のすべてのインスタンスを明示的にクリーンアップし、プロセスがすでに終了しています。

于 2012-04-28T17:29:44.603 に答える