タスクマネージャーを開き、[システム]領域の下を見て、以下を見ました。
スレッド:1337
ハイパースレッディングを使用できるデュアルコアプロセッサ(4つのスレッドを意味する)があるので、プロセッサに4つしか搭載されていないのに、どうして1000以上のスレッドを持つことができますか?
タスクマネージャーを開き、[システム]領域の下を見て、以下を見ました。
スレッド:1337
ハイパースレッディングを使用できるデュアルコアプロセッサ(4つのスレッドを意味する)があるので、プロセッサに4つしか搭載されていないのに、どうして1000以上のスレッドを持つことができますか?
回答:
簡単な答えは、すべてのスレッドが同時に実行されているわけではないということです。より詳細な説明については、以下をお読みください。
オペレーティングシステムのタスクスケジューラは、通常、アプリケーションをスケジュールするために考えられており、これにより、コンピューターが別のタスクを実行している間に1つのタスクを実行できます。昔は、マルチタスキングのリトマステストは、何か他のことをしながらフロッピーディスクをフォーマットしていました。OSを実際にテストしたい場合は、シリアルポートに接続されたモデム経由でファイルをダウンロードしながら、フロッピーディスクをフォーマットします。ハードウェアが実際に有意義な方法でそれを実行するのに十分なほど強力になったとき、ビデオ再生も時々そのようなテストで特集されました。OSのタスクスケジューラがそれらのタスクの実行をスムーズに処理できれば、何でも処理できます。
ただし、タスクスケジューラは実際にはアプリケーション(プロセス)をスケジュールせず、スレッドをスケジュールします。各アプリケーションには少なくとも1つのスレッドがありますが、潜在的に多数のスレッドを使用して、実行する作業を関連する部分または独立した部分に分割できます。たとえば、ユーザーインターフェイスを処理するスレッドが1つあり、ユーザーが潜在的に長時間実行される操作(印刷、スプレッドシートの再計算、開発環境など)を開始したときに別のスレッドを作成するのが一般的ですシンボル検索など)。プログラミング環境によっては、目に見えないほどプログラマーにある程度のスレッドが導入されます。たとえば、Javaと.NETはガベージコレクションを実行する場合がありますプログラマーの直接の制御外にある別のスレッドで。新しいスレッドの作成は比較的費用のかかる操作であるため、いくつかのプログラムは早い段階で多数のスレッドを作成してプールします(したがって、必要なたびにスレッドを作成する必要は必ずしもありません)。通常、プレビューを行うものはすべて別のスレッドで実行されるため、プレビューの生成中、UIの残りの部分は応答性を維持します。等々。まとめると、これはすべて、いつでもシステム上のスレッドの数がプロセスの数の何倍にもなりやすいことを意味します。
各スレッドは、考えられるいくつかの状態のいずれかになりますが、最も重要な違いは、実行中、実行可能、および待機中の状態です。用語はわずかに異なる場合がありますが、それは一般的な考え方です。いつでも、仮想コアごとに1つのスレッドのみ(ハイパースレッディングおよび類似の技術のため)CPUコアを実行できます(つまり、マシンコード命令を実行します)が、任意の数のスレッドを実行できます(つまり、取得する候補ですスケジューラーが次に実行するスレッドを決定する必要がある場合、CPU。待っています (ブロックとも呼ばれる)スレッドは、何かを待っているだけです-最も一般的なケースは、おそらくユーザー、ディスク、またはネットワークI / Oを待っていることです(特に、ユーザー入力は非常に遅いです)。
タスクマネージャに表示されるスレッド数は、これらの状態のスレッドの総数です。たとえば、これを入力しているWindows 7システムでは、現在約70のプロセスが開始されていますが、ほぼ900のスレッドがあります。さまざまなタスクを処理するためのすべてのバックグラウンドプロセスと、それらがそれぞれ多数のスレッドに分割される可能性があるため、これはとんでもない数ではありません。
プリエンプティブマルチタスクオペレーティングシステムのタスクスケジューラーの核となるのは、通常、技術的な実装の奥深くに行くと、通常何らかのハードウェア割り込みフックです。それが実行するための有用な作業を持っていないとき、カーネルはCPUを停止することができますことを、この手段(ない場合は、これは、ほぼ確実理由の一つである理由は、なぜLinuxはチェック命令を上のブート上のIA-32HLT
互換性のあるCPU、おそらく他のアーキテクチャで同様のチェックを行います)、合理的に確定した将来の時間に割り込みが発生し、タスクスケジューラが呼び出されるという知識で安全です。CPUが実行している他の作業に関係なく割り込みが発生するため(割り込みの背後にある考え方)、スケジューラは定期的に実行され、次のタイムスライスで実行するスレッドを決定する機会を得ます。コンテキストの切り替えは比較的高価なので、通常は(少なくともソースコードを介して)スケジューラーがスレッド間でどれだけ積極的に切り替えるかを調整できます。スレッドを切り替えると、システムの応答性が高くなりますが、切り替えのオーバーヘッドは、特定のタスクセットを完了するための全体の時間が長くなることを意味します。最速一方、このシステムは、オーバーヘッドを最小にするため、実行中のスレッドは、もはや(それが何かを待っているブロックされる、またはそれはその仕事を終えたという意味)を実行することができない場合にのみ、スレッド間の切り替え1になります最も応答システムがスレッドを切り替えます特定のスレッドがCPU時間を取得する前に待機する平均時間を最小化するため、スケジューラが呼び出されるたびに。通常、理想的な設定はこれら2つの間のどこかにあり、これらの選択のトレードオフが、Linuxが複数のスケジューラーとカーネル構成を介したいくつかのチューニングパラメーターを提供する大きな理由の1つです。
一方、協調的にマルチタスクするOSと環境(Windows 3.xがその一例です)は、各アプリケーションに依存して、スケジューラーに制御を定期的に委任します。通常、それを行うことを特に意図したAPI関数があり、多くのAPI関数は内部実行フローの一部としてそれを行います。これは、ユーザーエクスペリエンスをよりスムーズにするためです。この設計アプローチは、すべてのアプリケーションが正常に動作し、長時間の操作中に短い間隔で制御を譲る(1時間のほんの数分以上の長時間実行を意味する)限り機能しますが、詰まらないアプリケーションシステム全体。これは、OS 3。同じハードウェア上で同じタスクを実行しながら楽しそうに散歩しました:アプリケーションは、フロッピーディスクドライブに特定のセクターを書き込むように指示でき、呼び出しが返されるまでにかかる時間は実際に測定可能になりました(数十から数百ミリ秒またはもっと); プリエンプティブマルチタスクシステムでは、スケジューラが次にスケジュールされた呼び出しに割り込んで、現在「実行中」のスレッドが書き込み呼び出しによって実際にブロックされ、実行可能な別のスレッドに単に切り替えられることに注意してください。(実際にはもう少し複雑ですが、それが一般的な考え方です。)
プリエンプティブマルチタスク環境と協調環境の両方で、異なるスレッドが異なる優先度を持つ可能性もあります。たとえば、システム時間表示を更新するスレッドよりも、通信リンクを介してデータを受信しているスレッドをタイムリーに実行することがおそらく重要です。そのため、受信スレッドの優先度は高く、時間表示アップデータスレッドの優先度は低くなります。 。スレッドの優先度は、実行を許可するスレッドをスケジューラが決定する際に役割を果たします(たとえば、非常に単純化された、高優先度のスレッドは常に低優先度のスレッドの前に実行する必要があるため、低優先度のスレッドが処理を残していても、高優先度のスレッドが実行可能になった場合は優先されます)が、そのような特定のスケジューリングの決定は、基礎となるメカニズムの設計に影響しません。
1037台の車両がある4つの高速道路を考えてみてください。
OSは、多くのサービスで動作するために多くの実行プロセスを必要とします。最も単純なグラフィカルプログラムでさえ、マルチスレッドプログラミングが必要になります。多くのプログラムが開かれていることを考えると、計算能力リソースを共有する必要があることがわかります。
タスクマネージャーが表示しているのは、現在のシステム負荷です。あなたのcompスペックが示しているのは、(フロントエンドで)並列実行に受け入れられているスレッドの数です。ハイパースレッディングとマルチコア機能の違いをあまり考慮せずに、より論理的なフロントエンドスレッドを受け入れれば、システムのパフォーマンスは一般的に向上します。
DoEvents
てメッセージキューを処理しますが、同じスレッドで実行され、すべてのメッセージが処理されるまでその長時間実行操作をブロックします。(もちろん、Win32 API関数を呼び出したり、追加のプロセスを作成したりすることもできますが、その時点で下位言語のいずれかを使用することもできます。)
1つCPUを搭載したコンピューターに2つのスレッドを持たせるにはどうすればよいですか?
スレッドはソフトウェアエンティティであり、ハードウェアではありません。別のスレッドを作成するには、記述子構造やスタックなど、スレッドを構成するオブジェクト用のメモリが必要です。
オペレーティングシステムは、特定の割り込み(タイマー割り込みなど)内やスレッドがオペレーティングシステムを呼び出すときなど、さまざまなタイミングでスレッド間を切り替えます。
システムに存在するすべてのスレッドのうち、サブセットのみが通常「実行可能」と一般に呼ばれる状態にあります。実行可能スレッドは実行を熱望しています。実行中、または「実行キュー」に座って、スケジューラによるディスパッチを待機しています。実行可能でないスレッドは「ブロック」され、リソースの取得または入力の受信を待機します。または、「入力」が時間の経過である入力でブロックされているような「スリープ」です。「コンテキストスイッチ」は、オペレーティングシステムのスケジューラ機能がプロセッサの実行キューを調べ、実行する別のスレッドを選択したときに発生します。
特定のハードウェア機能に対するIntelの名前である「ハイパースレッディング」と混同しないでください。