LinuxのReceive()呼び出しでプロセスがブロック状態で待機しているかどうかを知ることはできますか?
-
06-07-2019 - |
質問
私の主な目的は、1つがreceive()を呼び出してブロックされるまでラウンドロビン方式でプロセスを1つずつ実行し、実行がキュー内の次のプロセスに切り替わるようにすることです。 Javaでコーディングされたコントローラーアプリケーションがあり、Runtime.getRuntime()。exec()を使用してこれらのプロセス(Javaアプリケーションでもある)を実行し、Processオブジェクトである戻り値を保持します。
この目的を達成するには、receive()呼び出し(またはブロックされている状態)をキャプチャし、それらをコントローラー(マスター)アプリケーションに伝える必要があります。
これが可能であれば、必要に応じて低レベルに移行できます。最初に考えたのは、ドライバーからこの情報を取得し、それをコントローラーJavaアプリケーションに伝えることでした。送受信操作をキャプチャするLinuxカーネルネットワークモジュールを作成しましたが、socket.receive()関数はネットワークドライバーに何も伝えません。
では、JVMからこの情報を取得するか、何らかの方法でlinuxコマンドから取得するか、またはおそらくlinuxカーネルモジュールから取得するのがオプションだと思いますか?
あなたの提案は何ですか?
解決
スレッドがブロックされているかどうか、またはブロックされているものを正確に知りたい場合は、スレッドダンプを取得するか、 jvisualvm を使用してプロセスにアタッチして確認します(jvisualvmではプロセスにアタッチし、スレッドダンプを取得します) 、各スレッドのアクティビティを確認します)。
他のヒント
systemtap をご覧になりましたか?最近のFedoraシステムですぐに利用できるはずです。
ベスト アンダース
これが役立つかどうかはわかりませんが、ローカル接続を使用して、マシン上のJavaスレッドの状態に関する情報を取得できます。
1)tools.jarをクラスパスに追加し、VirtualMachine.list()を使用して、マシンで実行中のJVMのリストを取得します。
2)VirtualMachine.attach(virtualMachineDescriptor)を使用して処理されたJVMにアタッチします
3)ローカルコネクタアドレスvm.getAgentProperties()。get(" com.sun.management.jmxremote.localConnectorAddress");を取得します
4)JMXConnectorFactory.newJMXConnector(...)を使用してJVMに接続します
5)JMX接続からThreadMXBeanをルックアップします
6)ThreadMXBeanから、JVM内のすべてのスレッドを記述するThreadInfosの配列を取得します。
7)TheadInfo#getThreadState()から、状態がThreadState.BLOCKEDであるかどうかを確認できます
ワーカープロセスでプロセス間通信プリミティブを使用して、データを受信する準備ができたことをコントローラーアプリケーションに通知する必要があります。
子プロセスがソケット読み取りを実装する方法について推測することはできません。ネットワークデータを待つためにrecv、select、またはpollなどを使用している可能性があります。
実際にはいくつかのポイントがあります。 Linuxスケジューラーは、ブロックされたタスクを先取りするのに十分スマートです。つまり、receive()を呼び出して、受信を待機しているものが何もない場合、おそらく呼び出しが戻るまでタスクはスリープ状態になります。スケジューリングを処理する必要はありません。 Linuxカーネルがそれを行います。
とはいえ、タスクが何らかのデーモンアプリケーションからブロックされているかどうかを知る必要がある場合、LKMを作成する場合は、興味のあるタスクリストにタスクを取得して、その状態?
もちろん、単純にタスクの状態をチェックするだけでは、正確に何が欲しいのか分からないかもしれません。タスクの状態が TASK_INTERRUPTIBLE
の場合、タスクが何かで待機していることを通知するだけですが、それが何かを理解するのは簡単なことではありません。同様に、タスクは TASK_RUNNING
状態になり、現時点では実際にCPUで実行されていません(ただし、少なくとも、タスクを知っている TASK_RUNNING
状態ではブロックされていません)。
QUITシグナル(コンソールでCtrl- \)を送信するだけで、スレッドダンプを取得できます。