2009-12-11 3 views
41

実行中のJavaスレッドとネイティブスレッドを区別するにはどうすればよいですか?JavaスレッドとOSスレッドを区別しますか?

Linuxでは、すべての子プロセスに対して親プロセスが存在し、0はすべてのプロセスの親であると言います。フォークされたすべてのJavaスレッドの親スレッドがありますか?

どのJavaスレッドがOSスレッドに関連しているかをどのように知るのですか(Javaスレッドがネイティブプロセススレッドを操作する場合)。

JavaスレッドとOSスレッドの命名規則はありますか。

実行中のJavaスレッドを別のJavaコードから中断または強制終了できますか?

+0

Stephen C、LinuxスレッドのネーミングとJavaスレッドのネーミングがどのように関係しているかを学習しています。また、LinuxでJVMスレッド管理をどのように管理するかについても説明します。 – karthi

答えて

61

Linuxでは、Javaスレッドはネイティブスレッドで実装されるため、スレッドを使用するJavaプログラムはスレッドを使用するネイティブプログラムと同じです。 「Javaスレッド」は、JVMプロセスに属する単なるスレッドです。

最新のLinuxシステム(NPTLを使用するシステム)では、プロセスに属するすべてのスレッドは同じプロセスIDと親プロセスIDを持ちますが、スレッドIDは異なります。 ps -eLfを実行すると、これらのIDが表示されます。 PID列はプロセスID、PPID列は親プロセスID、LWP列はスレッド(LightWeightプロセス)IDです。 「メイン」スレッドはプロセスIDと同じスレッドIDを持ち、追加のスレッドは異なるスレッドID値を持ちます。

古いLinuxシステムでは、NPTLの代わりに完全にPOSIXに準拠していない「linuxthreads」スレッド実装を使用することがあります。 linuxthreadsシステムでは、スレッドは異なるプロセスIDを持ちます。

システムのCライブラリ(libc)をスタンドアロンプ​​ログラムとして実行し、その出力で「使用可能な拡張子」を調べることで、システムがNPTLまたはlinuxthreadsを使用しているかどうかを確認できます。 「ネイティブPOSIXスレッドライブラリ」またはlinuxthreadsのいずれかを記述する必要があります。 Cライブラリへのパスはシステムによって異なります。/lib/libc.so.6,/lib64/libc.so.6(64ビットRedHatベースのシステム)、または/lib/x86_64-linux-gnu/libc.so.6(Ubuntuなどの最近のDebianベースのシステムでは)のようなものがあります。

OSレベルでは、theadsには名前がありません。それらはJVM内にのみ存在します。

pthread_kill() C関数を使用して特定のスレッドに信号を送ることができます。このスレッドを使用して、特定のスレッドをJVM外から取り除くことができますが、JVMがどのように応答するかはわかりません。それはちょうどJVM全体を殺すかもしれない。

+0

ワイアードありがとう、実行スレッドに名前を付けて、実行スレッドの詳細をクエリできますか?私はデバッグの観点から尋ねています。 – karthi

+0

スレッドの「名前」はJava固有です。デバッガを使ってJVMに接続する必要のある情報を確認することができます。 JVMの外側からは、数値IDのみが表示されます。これは、POSIXの観点からの唯一のIDです。 – Wyzard

+0

シェルプロンプトでJavaスレッド名を表示するにはどうすればよいですか? プロファイラまたはデバッガを実行中のJVMに接続すると、実行中のJavaスレッド名を取得してシェルスクリプトに供給できますか? – karthi

8

標準はありません。これは、使用しているJava実装に完全に依存します。また、「ネイティブスレッド」と「ネイティブプロセス」を混在させないでください。プロセスは、他のプロセスのアドレス空間を見ることができない独立したエンティティです。スレッドとは、ネイティブプロセスのアドレス空間で動作し、同じプロセスの他のスレッドをメモリに見ることができるものです。

Linuxで表示される内容は次のとおりです。Linuxのバージョンによっては、親プロセスのスレッドごとにプロセステーブルにエントリが作成されます。これらの「プロセス」は実際のプロセス(分離の意味で)ではありません。これらは、psコマンドで一覧表示できるスレッドです。親PID(PPID)を使用して作成したプロセスを見つけることができます。

4

JavaスレッドがOSスレッドにマッピングされる方法はまったくありません。すべてのJVM実装は、異なる方法でそれを実行できます。

green threadsと呼ばれる純粋なJavaスレッド実装もあります。これは、ネイティブスレッドがサポートされていない場合、またはシステムがマルチスレッド化されていない場合のフォールバックとして使用されます。お使いのOSに緑色のスレッドは表示されません。

実行中のJavaスレッドを別のJavaコードから中断または強制終了できますか?

同じJVMで実行している場合は、stop()を使用します。しかし、それは良い解決策ではなく、うまくいくかもしれません。 interrupt()はスレッドが安全にそれ自身をシャットダウンできるようにします。

私が知っているJVM以外のスレッドを殺す方法はありません。 OSが実際にスレッドの強制終了をサポートしている場合、Javaアプリケーションが後で正しく動作することは期待できません。

5

実行中のJavaスレッドは は別のJava コードから吊り下げたり死滅させることができることはできますか?

理論上はい。実際には、Thread.kill()Thread.suspend()のメソッドは非常に限られた状況を除いて安全でないため、推奨されていません。基本的な問題は、Javaスレッドを強制終了または一時停止することにより、Javaスレッドに依存する他のスレッドを混乱させる可能性があり、更新の途中であったかもしれない共有データ構造です。

"別のJavaコード"が別のJVMを意味する場合は、それが動作する可能性はさらに低くなります。関連するスレッド信号を送信する方法を理解したとしても、結果は完全に予測できません。私の賭けは、 "ターゲット" JVMがクラッシュするということです。

+0

JavaコードからLinuxコマンドを実行するだけで、特定のJVMで実行されている特定のスレッドを強制終了できます。 Windowsでもこれを行うことができます。しかし、あなたはおそらく、そのスレッドの子育てJVMをクラッシュさせるのは間違いないでしょう。両方のプログラムを制御している場合は、別のプロセスのスレッドが無意味に停止するようにするために、何らかの種類のIPC呼び出しを開発するべきでしょう。 – PSIXO

関連する問題