放課後プログラミング

調べたことや考えたことなどを忘れないために書きます。

プロセス内で別プロセスを呼んでやり取りする

親プロセスと子プロセス間でコミュニケーションを取りたい。その方法の簡単なメモ。

1. 別プロセスの実行

String cmd = "java HelloWorld"
ProcessBuilder pb = new ProcessBuilder(cmd.split(" "));
pb.start();

pb.start();を実行することでプロセスを実行できる。

2. 子プロセスとのやり取り(親プロセス側に書く)

Process p = pb.start();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));

try {
    bw.write(1 + "\n");
    bw.flush();

    return br.readLine();
} catch (IOException e) {
    return ""
}

1.でpb.start();したときの戻り値からOutputStreamとInputStreamを取得できる。それを便利なようにそれぞれBufferedWriterとBufferedReaderに変換しておく。
writerのwriteメソッドでメッセージを渡し、flushすることで、子プロセスの標準入力へと送りつけることができる。

3. 親プロセスとのやり取り(子プロセス側に書く)

Scanner scanner = new Scanner(System.in);

int num = scanner.nextInt();
System.out.println(num++);
System.out.flush();

標準入力を受けるScannerを作り、そこからnext()やnextInt()などを使って読み込めば良い。また、親プロセスにメッセージを送るには標準出力に出せば良い。
これで、子プロセスに数字を送るとインクリメントした値を親プロセスに返してきてくれるという無駄なやり取りができるようになった。

実際に意味のあるメッセージのやり取りを行う場合は、メッセージの形(プロトコル)を定義し、やり取りを行うのが良いと思う。例えば複数回メッセージのやり取りを行うのであれば、メッセージの終わりを示すルールを定義する(具体的には、最後の行を継続するしないのフラグとして、"CONTINUE"なら継続、"END"なら終了とする、といったルール)。当然その他のメッセージの内容にも何行目は何を示すかなどを定義し、お互いがそれに従って実装する必要がある。