1

長時間実行されるコンピューティング ジョブを実行するシングル スレッド プログラムがあります。メインスレッドはコンソールを出力に使用しています。ユーザーと対話してジョブの進行状況やプロセスの内部状態などを照会する別のスレッドを追加することを検討しています。

同期が適切に処理され、ユーザーがコマンド ライン コンソールなど (GUI は不要) を介して 2 番目のスレッドと対話すると仮定します。この機能を実装する良い方法は何ですか? 2 番目のスレッドを特定の名前付きパイプでコマンドを待機させ、ユーザーが GNU 画面のようなものを使用してこのパイプに接続できるようにすることができると思います (うまくいくかどうかはわかりません)。

これを実装するためのライブラリ (Java または非 Java) またはツールはありますか? 私のプログラムは Linux で実行されています。

4

2 に答える 2

1

ユーザーからの入力を読み取るには、別のスレッドが必要です。これが私がそれを行う方法です...

package com.mycompany.readthread;

import java.io.*;

public class Launcher {
    public static void main(String[] args) {
        new Launcher().run();
    }

    public void run() {
        LongRunningJob job = new LongRunningJob();
        ReadInputLoop readInputLoop = new ReadInputLoop(job);
        Thread readInputLoopThread = new Thread(readInputLoop);
        readInputLoopThread.start();  // run read input loop in another thread
        job.run();  // run long running job in this thread
    }

    class LongRunningJob implements Runnable {
        private double percentageComplete;

        @Override
        public void run() {
            // long running job
            // update percentageComplete in a synchronized block
        }

        public synchronized double getPercentageComplete() {
            return percentageComplete;
        }
    }

    class ReadInputLoop implements Runnable {
        private LongRunningJob job;               

        public ReadInputLoop(LongRunningJob job) {
            this.job = job;            
        }

        @Override
        public void run() {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            try {
                while (true) {
                    String line = br.readLine();
                    if ("exit".equalsIgnoreCase(line)) {
                        break;
                    }
                    if ("progress".equals(line)) {
                        double percentageComplete = job.getPercentageComplete();
                        System.out.println(String.format("%.3g", percentageComplete)+ "%");
                    }
                }                
            }
            catch (IOException ex) {
                System.err.println("Unexpected exception");
            }
        }
    }
}
于 2012-11-30T23:21:50.770 に答える
1

必要なことを行うには、実際には 2 つの名前付きパイプが必要です。各方向に 1 つです。この点では、ソケットを使用する方が良いオプションかもしれません (ただし、サーバー側で処理するのは少し難しいかもしれません)。

クライアントに関しては、GNU/Screen を使用してこれを行うことはできないと思います。名前付きパイプを使用する場合、クライアントは単純に使用する必要がありますcat(実際には 2 つのcatプロセス: 1 つはサーバーへの書き込み、もう 1 つは回答の読み取りです)。ソケットベースの通信を実装する場合は、クライアントにnetcat( ) を使用できます。nc

于 2012-11-30T23:02:51.877 に答える