2009-06-19 4 views
0

私の主な目的は、receive()を呼び出してブロックされるまで、ラウンドロビン方式でプロセスを1つずつ実行して、実行がキュー内の次のプロセスに切り替わるようにすることです。 Javaでコーディングされ、Runtime.getRuntime()。exec()を使用してこれらのプロセス(Javaアプリケーションでもある)を実行し、Processオブジェクトである戻り値を保持するコントローラアプリケーションがあります。LinuxでReceive()呼び出しでプロセスがBlocked状態で待機しているかどうかを知ることはできますか?

この目的を達成するには、receive()コール(またはブロックされている状態)をキャプチャして、コントローラ(マスター)アプリケーションに通知する必要があります。

可能であれば、私は低レベルにすることができます。私の最初の考えは、ドライバからこの情報を取得し、それをコントローラのJavaアプリケーションに伝えることでした。私は、送受信動作をキャプチャするLinuxカーネルネットワークモジュールを作成しましたが、AFAIK socket.receive()関数はネットワークドライバに何も伝えません。

私は、この情報をJVMから取得するか、何らかの理由でlinuxコマンドから取得するか、場合によってはLinuxカーネルモジュールから取得することを選択肢と考えていますか?

あなたの提案は何ですか?

答えて

1

、あなたのスレッドがブロックされているかどうかを知りたい、またはそれらが上のブロックされている正確に何をした場合は、スレッドダンプを取るか、またはプロセスに接続し、取るためにjvisualvmのようなツールを使用しますか、 (jvisualvmでは、プロセスにアタッチし、スレッドダンプを取ってから、各スレッドのアクティビティを調べます)。

+0

スレッドダンプ途中で... –

+0

スレッドはまだRunnable状態にあるようですが、スタックトレースからはaccept()、receive()などの呼び出しを見ることができます。これはトリックを行うと思われるが、ブロックされているかどうかをチェックし、出力を解析するためにjstackを~200 msごとに実行する必要があるだろう(これはパフォーマンス上あまり良くない)それがreceive()などの呼び出しでブロックされたときに私に信号を送るようにします。それは良い解決策です。それが起こったときに(ほとんど)それを捕まえる必要はなかった。 – Ozan

0

ワーカープロセスでプロセス間通信プリミティブを使用して、データを受信する準備ができていることをコントローラアプリケーションに通知する必要があります。

子プロセスがソケット読み取りをどのように実装するかを前提にすることはできません。ネットワークデータを待つためにrecv、select、pollなどを使用している可能性があります。

+0

確かに可能ですが、これはプロセスのコードを変更する必要があります。私のもう1つの目的は、(ほとんど)どのプロセスでも動作するように、私がこれらのプロセスから得ることができるように独立していることです。 – Ozan

1

systemtapを見ましたか?最近のFedoraシステムですぐに利用できるはずです。

ベスト アンダース

+0

これは、ソケットのカーネルシステムコールをキャプチャしているようです。どちらが私が信じる最良のオプションです。それ以外の場合、Javaアプリケーション固有のものになります。私はそれをインストールしてUbuntu 9.04で試してみることができませんでした。なぜなら、カーネルのデバッグライブラリなどについて不平を言っていたからです。そして今はそれに対処する時間がありません。これは私が考える最良の方法です。スタックトレースを取得し、それを解析するには、読み込み中にブロックする多くのソケットなどのクラス関数を探す必要があります。 – Ozan

0

ここで実際にいくつかの点があります。 Linuxスケジューラは、ブロックされたタスクを先取りできるほどスマートです。つまり、receive()を呼び出して受信待ちの何もない場合は、コールが戻るまでスリープ状態になります。スケジューリングを処理する必要はありません。 Linuxカーネルがそれを行います。

これは、あなたのタスクがデーモンアプリケーションからブロックされているかどうかを知る必要がある場合、LKMを書く意思がある場合は、興味のあるタスクリストにタスクを入れるだけでなく、その状態を確認しますか?

もちろん、タスクの状態を確認するだけで、必要なものが正確に表示されない場合があります。あなたの仕事の状態がTASK_INTERRUPTIBLEの場合、あなたの仕事はの何かを待っているだけですが、それが何かを理解するのは簡単なことではないかもしれません。同様に、あなたのタスクはTASK_RUNNING状態にあり、現時点でCPU上で実際に実行されているわけではありません(少なくとも、TASK_RUNNING状態では、あなたのタスクはブロックされていません)。

1

これが役立つかどうかは分かりませんが、ローカルアタッチを使用してマシン上のJavaスレッドの状態に関する情報を得ることができます。

1)ツールを追加します。jarをクラスパスに追加し、VirtualMachine.list()を使用して実行中のJVMのリストを取得します。

2)JVMへのアタッチは、ローカルのコネクタアドレスを取得します)

3)VirtualMachine.attach(VirtualMachineDescriptorがを使用して処理、vm.getAgentProperties()。取得( "com.sun.management.jmxremote.localConnectorAddress") ;

4)使用JMXConnectorFactory.newJMXConnector(...)は、ThreadInfosの配列を取得ThreadMXBeanからThreadMXBean

6)をアップルックアップJMX接続からJVM

5)に接続することJVM内のすべてのスレッドを記述します。 TheadInfo#getThreadState(から

7))あなたは、スレッドダンプを取得するために)状態が

+0

私はこれを試していませんが、JStackを使用するとThread.State:RUNNABLEが得られます。私はスレッドの状態からこの情報を得ることができないように見えます。 – Ozan

0

をThreadState.BLOCKEDされている場合は、単にコンソールにQUITシグナル(はCtrl- \を送ることができます確認することができます。

関連する問題