プロセスの切り替えには常にスレッドの切り替えが含まれるため、これらを逆の順序で説明する方がはるかに簡単です。
シングルコア CPU での典型的なスレッド コンテキスト スイッチは、次のように発生します。
すべてのコンテキスト スイッチは、「割り込み」によって開始されます。これは、ドライバーを実行する実際のハードウェア割り込み (ネットワーク カード、キーボード、メモリ管理またはタイマー ハードウェアなどから)、またはハードウェア割り込みのような呼び出しシーケンスを実行するソフトウェア呼び出し (システム コール) である可能性があります。 OSに入ります。ドライバー割り込みの場合、OS は、「通常の」直接割り込みリターンを実行する代わりにドライバーが呼び出すことができるエントリ ポイントを提供し、OS がスレッドを設定する必要がある場合、OS スケジューラーを介してドライバーを終了できるようにします。準備完了 (例: セマフォを通知した)。
重要なシステムは、カーネルコード/データなどにアクセスできるように、ハードウェア保護レベルの変更を開始してカーネル状態に入る必要があります。
中断されたスレッドのコア状態を保存する必要があります。単純な組み込みシステムでは、すべてのレジスタをスレッド スタックにプッシュし、スタック ポインタをスレッド制御ブロック (TCB) に保存するだけかもしれません。
多くのシステムは、この段階で OS 専用スタックに切り替えて、OS 内部スタック要件の大部分がすべてのスレッドのスタックに影響を与えないようにします。
ネストされた割り込みを可能にするために、割り込み状態への変更が発生したスレッドスタック位置をマークする必要がある場合があります。
ドライバー/システム コールが実行され、さまざまなスレッド優先度の内部キューに TCB を追加/削除することで、準備完了スレッドのセットを変更できます。ネットワーク カード ドライバがイベントを設定したり、別のスレッドが待機しているセマフォを通知したりして、スレッドが準備完了セットに追加されるか、実行中のスレッドが sleep() を呼び出して、準備完了セットから自身を削除することを選択した可能性があります。 .
OS スケジューラ アルゴリズムは、次に実行するスレッドを決定するために実行されます。通常は、その優先度のキューの先頭にある最高優先度の準備完了スレッドです。次に実行するスレッドが、以前に実行したスレッドとは異なるプロセスに属している場合は、ここで追加の処理が必要になります (後述)。
そのスレッドの TCB から保存されたスタック ポインターが取得され、ハードウェア スタック ポインターに読み込まれます。
選択したスレッドのコア状態が復元されます。私の単純なシステムでは、選択したスレッドのスタックからレジスタがポップされます。より複雑なシステムでは、ユーザー レベルの保護への復帰を処理する必要があります。
割り込みリターンが実行されるため、実行は選択されたスレッドに転送されます。
マルチコア CPU の場合、事態はより複雑になります。スケジューラは、現在別のコアで実行されているスレッドを停止し、準備ができたばかりのスレッドに置き換える必要があると判断する場合があります。これは、プロセッサ間ドライバーを使用して、停止する必要があるスレッドを実行しているコアをハードウェアで中断することによって実行できます。他のすべてのものに加えて、この操作の複雑さは、OSカーネルの作成を避ける正当な理由です:)
典型的なプロセス コンテキスト スイッチは、次のように発生します。
プロセス コンテキストの切り替えは、スレッド コンテキストの切り替えによって開始されるため、上記の 1 ~ 9 のすべてが発生する必要があります。
上記の手順 5 で、スケジューラは、以前に実行されていたスレッドを所有していたプロセスとは異なるプロセスに属するスレッドを実行することを決定します。
メモリ管理ハードウェアには、新しいプロセスのアドレス空間、つまり、新しいプロセスのスレッドがそのメモリにアクセスできるようにするセレクタ/セグメント/フラグなどをロードする必要があります。
FPU ハードウェアのコンテキストは、PCB から保存/復元する必要があります。
保存/復元が必要なプロセス専用ハードウェアが他にもある場合があります。
実際のシステムでは、メカニズムはアーキテクチャに依存しており、上記はいずれかのコンテキスト スイッチの影響についての大まかな不完全なガイドです。厳密にはスイッチの一部ではない、プロセス切り替えによって生成されるその他のオーバーヘッドがあります。プロセス切り替え後に余分なキャッシュ フラッシュとページ フォールトが発生する可能性があります。以前に実行されていたスレッドを所有するプロセスに。