David、templatetypedefなどによって提供された優れた回答に直接追加することはできません-スレッド間通信の遅延とリソースの浪費を避けたい場合は、sleep()ループでスレッド間通信を行わないでください。
先制スケジューリング/ディスパッチ:
CPU レベルでは、割り込みが重要です。OS は、そのコードが入力される原因となる割り込みが発生するまで何もしません。OS 用語では、割り込みには 2 つのフレーバーがあることに注意してください。ドライバーを実行させる「実際の」ハードウェア割り込みと「ソフトウェア割り込み」です。これらは、実行中のスレッドのセットを潜在的に引き起こす可能性がある、既に実行中のスレッドからの OS システム コールです。変更する。キープレス、マウスの動き、ネットワーク カード、ディスク、ページ フォールトはすべて、ハードウェア割り込みを生成します。待機関数とシグナル関数、および sleep() は、その 2 番目のカテゴリに属します。ハードウェア割り込みによってドライバーが実行されると、ドライバーは設計されたハードウェア管理を実行します。ドライバーが OS にスレッドを実行する必要があることを通知する必要がある場合 (おそらく、ディスク バッファーがいっぱいになり、処理する必要があります)、
上記の例のような割り込みは、待機していたスレッドを実行できるようにするか、実行中のスレッドを待機状態にすることができます。割り込みのコードを処理した後、OS はそのスケジューリング アルゴリズムを適用して、割り込みの前に実行されていたスレッドのセットが、現在実行されるべきスレッドのセットと同じかどうかを判断します。そうである場合、OS は単に割り込みを返します。そうでない場合、OS は実行中のスレッドの 1 つ以上を横取りする必要があります。割り込みを処理したものではない CPU コアで実行されているスレッドを OS が横取りする必要がある場合、OS はその CPU コアの制御を取得する必要があります。これは、「実際の」ハードウェア割り込みによって行われます。OS のプロセッサ間ドライバーは、プリエンプトされるスレッドを実行しているコアをハード割り込みするハードウェア信号を設定します。
プリエンプトされるスレッドが OS コードに入ると、OS はそのスレッドの完全なコンテキストを保存できます。一部のレジスタは、割り込みエントリによってスレッドのスタックに既に保存されているため、スレッドのスタックポインタを保存すると、これらすべてのレジスタが効果的に「保存」されますが、通常、OS はさらに多くのことを行う必要があります。例えば。キャッシュをフラッシュする必要がある場合、FPU の状態を保存する必要がある場合があります。実行する新しいスレッドがプリエンプトされるプロセスとは異なるプロセスに属している場合は、メモリ管理保護レジスタをスワップアウトする必要があります。 . 通常、OS は、割り込みスレッド スタックからプライベート OS スタックにできるだけ早く切り替えて、すべてのスレッド スタックに OS スタック要件が課されるのを回避します。
コンテキストが保存されると、OS は、実行される新しいスレッドの拡張コンテキストを「スワップイン」できます。これで、OS は最終的に新しいスレッドのスタック ポインターをロードし、割り込みリターンを実行して、新しい準備ができたスレッドを実行できるようになります。
その後、OS は何もしません。実行中のスレッドは、別の割り込み (ハードまたはソフト) が発生するまで実行されます。
重要なポイント:
1) OS カーネルは、中断されたスレッドとは異なる一連のスレッドに割り込みを返すことを決定できる大きな割り込みハンドラーと見なす必要があります。
2) OS は、スレッドの状態や実行中のコアに関係なく、任意のプロセスの任意のスレッドを制御し、必要に応じて停止できます。
3) プリエンプティブなスケジューリングとディスパッチは、これらのフォーラムに投稿されているすべての同期などの問題を生成します。大きな利点は、ハード割り込みに対するスレッドレベルでの応答が速いことです。これがなければ、PC で実行するすべての高性能アプリ (ビデオ ストリーミング、高速ネットワークなど) は事実上不可能になります。
4) OS タイマーは、実行中のスレッドのセットを変更できる大きな割り込みセットの 1 つにすぎません。「タイムスライシング」(うーん、私はその用語が嫌いです)、準備ができているスレッド間で、コンピューターが過負荷になっている場合にのみ発生します。準備ができているスレッドのセットは、それらを実行するために使用できる CPU コアの数よりも大きくなっています。OS のスケジューリングを説明するテキストで、「割り込み」の前に「タイム スライス」に言及している場合、説明よりも混乱を招く可能性があります。タイマー割り込みは、多くのシステム コールが主要な機能をバックアップするためのタイムアウトを持っているという点で「特別」です (OK、sleep() の場合、タイムアウトは主要な機能です:)。