誰かがプリエンプティブスレッドモデルと非プリエンプティブスレッドモデルの違いを説明できますか?
私の理解に従って:
誰かがお願いできますか:
yield()
(または何でも)を呼び出すのはそのスレッド次第です。非プリエンプティブスレッドは、協調スレッドとも呼ばれます。これらの例はPOE(Perl)です。別の例は、クラシックなMac OS(OS Xより前)です。協調スレッドは、あきらめるまでCPUを排他的に使用します。次に、スケジューラは別のスレッドを選択して実行します。
プリエンプティブスレッドは、協調スレッドと同じように自発的にCPUを放棄することができますが、そうしない場合は、CPUから奪われ、スケジューラーは別のスレッドを開始します。 POSIXおよびSysVスレッドはこのカテゴリに分類されます。
協調スレッドの大きな利点は、効率が向上し(少なくともシングルコアマシンで)、並行性の処理が容易になることです。制御を放棄する場合にのみ存在するため、ロックは必要ありません。
プリエンプティブスレッドの大きな利点は、フォールトトレランスが向上することです。単一のスレッドが生成に失敗しても、他のすべてのスレッドの実行が停止するわけではありません。また、複数のスレッドが同時に実行されるため、通常はマルチコアマシンでより適切に機能します。最後に、あなたが絶えず降伏していることを確認することについて心配する必要はありません。これは、非常に厄介なことです。たとえば、大量の処理ループです。
もちろん、それらを混ぜることもできます。単一のプリエンプティブスレッドでは、その内部で多数の協調スレッドを実行できます。
non-preemptiveを使用しても、プロセスがI/Oを待機しているときにプロセスがコンテキストの切り替えを実行しないわけではありません。ディスパッチャは、スケジューリングモデルに従って別のプロセスを選択します。プロセスを信頼する必要があります。
非プリエンプティブ:
少ないコンテキスト切り替え、少ないオーバーヘッド非プリエンプティブモデルで賢明な場合があります
シングルコアプロセッサで処理できるため、処理が簡単
プリエンプティブ:
利点:
このモデルでは、実行中のプロセスをより詳細に制御するのに役立つ優先順位があります
同時実行性の向上は跳ね返ります
システム全体をブロックせずにシステムコールを処理する
欠点:
同期にはより複雑なアルゴリズムが必要で、クリティカルセクションの処理は避けられません。
それに伴うオーバーヘッド
cooperative(non-preemptive)モデルでは、スレッドに制御が渡されると、明示的に制御が渡されるかブロックされるまで実行が継続されます。
プリエンプティブモデルでは、仮想マシンは、いつでも1つのスレッドから別のスレッドに制御を移すことができます。どちらのモデルにも長所と短所があります。
Javaスレッドは一般に、優先度の間で優先されます。優先度の高いスレッドは、優先度の低いスレッドよりも優先されます。優先度の高いスレッドがスリープまたはブロックした場合、優先度の低いスレッドを実行できます(利用可能なスレッドがあり、実行の準備ができていると想定)。
ただし、優先度の高いスレッドが起動またはブロック解除されるとすぐに、優先度の低いスレッドが中断され、終了するか、再びブロックされるか、さらに優先度の高いスレッドによって横取りされるまで実行されます。
Java言語仕様では、VMが実行可能な優先度の高いスレッドではなく、優先度の低いスレッドを実行できる場合がありますが、実際にはこれは異常です。
ただし、Java言語仕様では、同等の優先度のスレッドで何が起こるかを指定していません。一部のシステムでは、これらのスレッドはタイムスライスされ、ランタイムは特定の時間を割り当てます。その時間が終了すると、ランタイムは実行中のスレッドをプリエンプトし、同じ優先順位を持つ次のスレッドに切り替えます。
他のシステムでは、実行中のスレッドが優先されず、同じ優先度のスレッドが優先されます。ブロックするか、明示的に制御を渡すか、優先順位の高いスレッドによって横取りされるまで、実行を続けます。
利点に関しては、デロベルトとプオリアの両方がそれらを非常にはっきりと強調しています。