レビュー
前の記事を想起し、我々は並行プログラミングを学ぶために私たちのJavaのより良い知識を目的としている現代のコンピュータモデル、CPUのキャッシュ・コヒーレンシ・プロトコル、CPUやメモリ作品を紹介しました。
入門
本稿では、概念を理解するために来て、スレッドは何ですか?Javaスレッド内のスレッドとコンピュータの違いは何ですか?
スレッドとは何ですか
現代のオペレーティングシステムプロセスを作成するプログラムを実行するとき。例えば、オペレーティングシステムはプロセスを作成し、Javaプログラム、Webページ、ソフトウェアアプリケーションを起動します。現代の原子操作システムCPUスケジューリングも軽量プロセス(軽量プロセス)と呼ばれ、スレッドである、あなたがプロセスで複数のスレッドを作成することができ、これらのスレッドは独自のスタック、ローカル変数、カウンターやその他の財産、缶を持っています共有メモリ変数へのアクセス。これらのスレッドのプロセッサを高速スイッチング、我々は同時に、これらの同時実行スレッドを感じるので。
プロセスがリソース割当システムの基本ユニットは、スレッドがCPUスケジューリングの基本単位、実行(メインスレッド)の少なくとも一つのスレッドを含むプロセスであり、プロセスでそれらに取り付けられたスレッドは、各スレッドは、(現在のスレッドの変数に保存)レジスタのセットを有しますスタックは、(各フレームはプロセスを保存したが、既に呼び出しを返さなかった場合、実行履歴を記録する)、プログラムカウンタ(記録動作は、次の命令を実行します)
CPUのタイムスライスがすぐに同時達成するためにスレッドを切り替え、その後、コードブロックを実行するスレッドを提供します。
JVMのスレッドで私たちが直接CPUを運営されていないことを知っておく必要があり、JVMは、基礎となるオペレーティング・システムに依存し、したがって、ねじの種類をコンセプトをもたらすでしょう。
###オペレーティング・システムのスペース
- カーネル空間
- コアシステム、基礎となるプロセス
- ユーザ空間
- JVM
- アプリケーション日食
- ビデオプレーヤー
ねじの種類
- ユーザーレベルのスレッド(ユーザーレベルのスレッド)
- ラインカーネルスレッド(カーネルレベルスレッド)
CPUレベル
リング0、RING1、RING2、RING3:IntelのCPUの特権レベルは4つのレベルに分かれています。Windowsのみ1二つのレベルリング0とRING3、リング0のみ使用されるオペレーティングシステムへの使用、RING3の誰でも使用することができます。リング0の一般的な命令を実行するためのアプリケーションを試みた場合、Windowsは、「不正な命令」のエラーメッセージが表示されます。ユーザ空間では、JVMは、レベルULTスレッドを作成するだけでリング3レベルの権限を持つことができます。
リング0レベルULTは、この部門理由として、操作を呼び出すことができませんか?
任意のULTは、CPUを動作させることができれば、セキュリティ上の理由から出発は、理不尽な攻撃へのJVMのスレッドは、データを他のプロセスの指示を変更することを、リング0レベルを持っています。これは、セキュリティ上の問題につながることができます。限定されないが、カーネル内部の命令を変更することができるというウイルスは、移植の無料です。
###スレッドのスケジューリング
JVMは、カーネルレベルのスレッドを生成する必要がある場合、それはどのように操作することができますか?
KLTレベル(JNI)提供カーネルのシステムコールインタフェース空間を呼び出すことにより、スレッドを作成するために行くことができます。
彼らはCPUを使用して行くことができる前に、KLTレベルのスレッドを作成した後、それが割り当てられたタイムスロットとなります。
ユーザースレッド
ユーザプログラムのスレッドで実装カーネルのサポートを必要としないこと、それはライブラリが制御ユーザスレッドへのアプリケーション・プロセスの作成、同期、スレッドのスケジューリング、および管理機能を提供し、スレッドを使用して、オペレーティングシステムのカーネルに依存しません。また、ユーザー・スレッドは、オペレーティングシステムのカーネルとは独立して、スレッドライブラリを使用して、アプリケーション・プロセスによって作成および管理されています。これは、ユーザーモード/カーネルモード切り替え(コンテキストスイッチ)、スピードを必要としません。スレッドブロックが(そのすべてのスレッドを含む)全体のプロセスがブロックさになるだろうように、オペレーティングシステムのカーネルは、マルチスレッドの存在を知りません。ここでプロセッサ時間スライス割当処理は、基本的な単位であるので、実行の相対的減少の各スレッドの時以来。
カーネルスレッド
すべてのスレッド管理操作は、オペレーティングシステムのカーネルによって行われます。保存カーネルスレッドとコンテキスト情報の状態、スレッドのコールを遮断することによって引き起こされるシステムを実行している場合、カーネルはプロセスの他のスレッドをスケジュールすることができます。マルチプロセッサシステムでは、カーネルは、並列処理の実行度を向上させるために複数のプロセッサ上で実行されている同じプロセスに属する複数のスレッドを割り当てることができます。、スケジュールの作成、および管理のニーズの完全なカーネルスレッド、ユーザレベルスレッドとこれらの操作がはるかに遅いと比べてそうに、それでも速い操作を作成し、管理するプロセスよりもため。このようは、Windows、Linuxなど、市場にほとんどのオペレーティングシステムは、すべてのカーネルレベルのスレッドをサポートしています。
私たちは、その特定のユーザの空間に対応するスレッド、KLT、プロセスの各スレッド、カーネルに接続されているすべてのを見て、カーネルはそれが小型軽量プロセスとして理解することができ、対応表をスレッド化する必要があります特定のタスクだけでなく、リング0 CPUの特権レベルを持っています。
Javaはここで、スレッドのレベルを作成しましたか?
- 1.2、ULTを作成
- 1.2後、KLTを作成
private native void start0();
复制代码
Javaスレッドとカーネルスレッドの関係
あなたはJVMのスレッドスケジューラは、カーネル空間とカーネル空間のスレッドテーブルの関係におけるカーネルスレッドを生成するために、ライブラリの呼び出しを通過します作成した後に、1つのマッピングの対応を行います。
スレッドを作成するためのJava
- 新しいjava.lang.Threadの()。()開始
- ネイティブスレッドにJNIを使用すると、JVMに接続します
新しいjava.lang.Threadの()。[スタート]()この方法では、場合にのみ、唯一の本当のスタート()メソッドを呼び出します
スレッドを作成するためのJVM、ライフサイクルの主要なステップ
- 対応JavaThreadのインスタンスを作成します
- 対応OSThreadのインスタンスを作成します
- 実際の基礎となるオペレーティング・システムのネイティブスレッドを作成します。
- JVMは、メモリの割り当てなどの適切な状態を、準備のThreadLocal
- 実行するためにネイティブスレッドを開始する基礎となる、実行オブジェクトが生成されたjava.lang.Threadの呼び出し()メソッド
- 例外終了をメソッドが終了した後に生成されたjava.lang.Threadの()が返すのオブジェクトを実行するか、または投げ、終了ネイティブスレッド
- 対応JavaThreadとOSThreadをクリアするには、関連するJVMスレッドリリースリソース
ネイティブスレッドのJNIは、JVMへの主要なステップを添付します
- JVMインスタンスJNI呼び出しで実行されるアプリケーションに接続AttachCurrentThread
- JVMは、適切なオブジェクトJavaThreadとOSThreadを作成します
- 対応するオブジェクトを作成したjava.lang.Thread
- 作成したオブジェクトのjava.lang.Threadの後は、JNIは、あなたは、Javaコードを呼び出すことができます
- JNI呼び出しDetachCurrentThread、JNI経由した後JVMインスタンスから切断します
- JVMは、適切なJavaThread、OSThread、java.lang.Threadのオブジェクトをクリア
Javaスレッドのライフサイクル
図に示すように。
なぜ使用の並行処理?同時何が問題でしょうか?
なぜ使用の同時
実際には、並行プログラミングの本質は、近代的なマルチコアCPUの文脈では、マルチスレッド技術を使用することで、並行プログラミングのトレンドを生み出し、あなたは極端に並行プログラミング、マルチコアCPUのコンピューティングパワーの形で再生することができ、パフォーマンスが改善されました。また、複雑なビジネス・モデルの顔は、並列プログラムは、シリアルプログラム、および優れたこの事業分割に合わせて並行プログラミングよりビジネスニーズに、より応答します。
でもシングルコアプロセッサは、各スレッドにCPUタイムスライスを割り当てることによって、これを達成するために、マルチスレッド・コードの実行、CPU機構をサポートします。時間が非常に短い作品ですので、CPUのタイムスライスは、常に実行スレッドを切り替えることによりCPUは、私たちは複数のスレッドが同時に実行されている感じさせるので、タイムスライスは、通常、数十ミリ秒(ms)であり、時間の各スレッドに割り当てられています。
並行性は等しく平行ではない:並行処理は、並行して、交互にタスクの数を意味する真の意味で「同時」と呼ばれます。1つのCPUのみが存在する場合、実際には、複数のスレッドを使用している間、あなたは、システム内の実際のシステム環境が唯一タイムスライスを交互によって切り替え、およびタスクの同時実行になることができる平行することはできません。真の並列は、複数のCPUを持つシステムで発生する可能性があります。
同時メリット
- マルチコアCPUの計算された全容量を使用しました。
- アプリケーションのパフォーマンスを向上させ、サービススプリッタを促進します。
並行性の問題が生じます
- 頻繁にコンテキストの切り替えにつながる高度に同時シナリオ、
- クリティカルセクションスレッド安全性の問題は、デッドロックしやすく、デッドロックが利用できないシステムになります
- 他の
これは、タスクのタイムスライス、現在のタスクの実行のタイムスライスを実行するためにCPUサイクルで次のタスク割り当てアルゴリズムに切り替わります。しかし、スイッチの前に、タスクの状態が保存されますので、次の状態がタスクに戻るにすることを、あなたは、このタスクをロードすることができます。だから、タスクは、リロードのプロセスからコンテキストスイッチを保存することです。
手順を切り替えるスレッドコンテキスト:
コンテキスト切り替え
数フレームのために予約のLinuxカーネルのコードとデータ構造は、これらのページをディスクにロールアウトされることはありません。ユーザコードとカーネル・コードによって0xc0000000(PAGE_OFFSET)に0x00000000のから(即ち、ユーザ空間)線形アドレス参照。0xc0000000(PAGE_OFFSET)0xFFFFFFFFFから線形アドレスにのみカーネルコードによって(すなわち、カーネル空間)にアクセスすることができます。カーネルのコードとデータ構造は、アドレス空間のこの1ギガバイトに配置されるが、このアドレス空間、より大きな消費者の仮想アドレスから物理アドレスへのマッピングのためにしなければなりません。
メモリ4 GB、わずか3 GBはユーザアプリケーションのために使用することができることをこれは意味。プロセスは、ユーザーモード(ユーザーモード)またはカーネルモード(kernelmode)で実行することができます。ユーザーのユーザーモードで実行中のプログラム、およびシステムコールは、カーネルモードで実行します。両方の方法では、異なるスタックを使用:一般ユーザモードスタックを使用して、固定サイズのスタック(典型的には、メモリページサイズ)とカーネルモード。
各プロセスは、彼らが共有し、カーネル空間の1ギガバイトを独自の3 Gのユーザースペースがあります。プロセスがユーザ空間からカーネル空間に入ると、それはもはや、独自のプロセス空間アップを持っていません。私たちは、多くの場合、そのスレッドのコンテキストスイッチは、カーネルモードの理由の嘘にユーザーモードへの切り替えを伴うと言う理由です。
例えば上記図、導入するため、CPUコンテキスト切り替え
第一歩
時刻が到来時間スライスA、関連するサービスロジック実行、CPUカートンタイムスライス実行スレッドB Bを適用するスレッド
この時点でスレッドは、後に継続するために、一時的な中間状態に格納する必要があります。
結果は、CPUレジスタによって実行される--->キャッシュ - >メインメモリに書き戻すバスBUS(キャッシュ・コヒーレンシ・プロトコル)によって。
いくつかの中間状態と呼ばれる、メインメモリのカーネル空間に格納されるTss任务状态段
ローカルの記憶プログラム命令、プログラムポインタ、中間データなどが挙げられます。
第二のステップ
実行時間スライスBは、スレッドAのシートAの実行後の時間を指すように続けます
CPU時間は、再記憶したいload
タイムスライス命令の実行、プログラムポインタ、中間データにプログラムの中間結果。
そして、論理スレッドAの実行を再開
#概要
この記事では、知識は、関連スレッド、同時実行、コンテキストスイッチ、およびあなたの助けに希望が何であるかを説明します。