00:00 — プロセススケジューリングの基本#
プロセススケジューリングの目的は、複数のプロセスへCPU時間を合理的に配分することです。プロセスが自発的にCPUを返すだけでは、無限ループに入ったプロセスやCPUを長時間使い続けるプロセスによって、他のプロセスが実行できなくなる可能性があります。
そこでOSはタイマー割り込みを利用します。一定時間が経過すると割り込みが発生し、カーネルは実行中のプロセスを切り替えます。これがプリエンプティブスケジューリングの基本です。
プロセスの状態は、概念的には次のように管理されます。
- 実行待ちキュー(ready queue):CPUの割り当てを待っているプロセス。
- 待ちキュー(wait queue):I/O、ロック、イベントなどを待っているプロセス。
- 実行中:現在CPU上で動いているプロセス。
たとえば5つのプロセスがあり、スケジューラーが一定間隔で切り替えるとします。プロセスAがI/O待ちになった場合、Aを待ちキューへ移し、別の実行可能なプロセスを選べば、CPUを無駄に待機させずに済みます。
02:09 — プロセスが多いと遅くなる理由#
プロセス数が数百、数千に増えると、各プロセスへ短い時間だけCPUを割り当てる方式は、切り替えのコストを無視できなくなります。
コンテキストスイッチでは、レジスター、スタック、アドレス空間などの実行状態を保存し、次のプロセスの状態を読み戻します。たとえば、各プロセスの実行時間が10msで切り替え自体に1msかかるなら、CPU時間の一部が切り替えだけで消費されます。
時間片を短くすれば応答性は上がりますが、コンテキストスイッチは増えます。逆に時間片を長くすれば効率は上がりやすい一方、対話的な処理の応答が遅くなります。スケジューラーはこのトレードオフを調整します。
02:47 — 2つのキューを使う考え方#
教材では、実行可能なプロセスをactiveキューとexpiredキューに分けるモデルを使うことがあります。
- activeキュー:現在のラウンドで実行対象になるプロセス。
- expiredキュー:時間片を使い切り、次のラウンドを待つプロセス。
activeキューが空になると、2つのキューを交換します。こうすると、同じプロセスだけがCPUを占有し続けることを防ぎ、待っているプロセスにも実行機会を与えられます。
たとえば、次のような状態を考えます。
active : [A, B, C]
expired : [D, E]A、B、Cの時間片が尽きてactiveキューが空になると、キューを交換し、DとEを実行対象にします。これはスケジューラーの公平性を説明するためのモデルであり、現行Linuxの内部実装をそのまま表したものではありません。
05:33 — 優先度と時間配分#
優先度を使うスケジューラーでは、プロセスごとにCPUの配分を変えます。単純なモデルでは、高い優先度のプロセスへ短い時間片を頻繁に割り当てたり、優先度に応じて異なる重みを設定したりします。
しかし、優先度が1段階違うだけでCPU時間が大きく変化すると、公平性が損なわれる可能性があります。そのため、実際のスケジューラーでは、優先度、重み、待ち時間、実行済み時間、対話性などを組み合わせて判断します。
07:01 — 重みによる配分#
重み付きスケジューリングでは、各プロセスの重みに応じてCPU時間を配分します。たとえば、Aの重みが1、Bの重みが2なら、理想的にはBがAの約2倍のCPU時間を得ます。
ただし、実際の実行ではI/O待ち、スリープ、最低時間片、優先度、CPUコア数なども影響します。時間片をすべて使わずにブロックしたプロセスは、後で早く選ばれる場合があります。重みだけを掛け算すれば常に同じCPU時間になるわけではありません。
09:02 — 仮想実行時間#
公平性を説明する代表的な考え方が、仮想実行時間(virtual runtime)です。各プロセスが実際に消費したCPU時間を、重みなどに応じて補正して記録します。仮想実行時間が小さいプロセスを優先すれば、長く待っているプロセスへCPUを戻せます。
このような候補を効率よく選ぶために、スケジューラーが木構造などのデータ構造を使うことがあります。典型的な説明では、仮想実行時間の小さいプロセスを素早く見つけられるように、最小値を先頭付近に保持します。
Linuxのスケジューリング実装は、カーネルのバージョンやスケジューリングクラスによって変化します。O(1)スケジューラー、CFS、より新しいスケジューラーを同一視せず、ここでは「公平にCPUを分配するための考え方」として理解してください。
まとめ#
- タイマー割り込みによって、プロセスがCPUを返さなくても切り替えられる。
- 実行可能なプロセスは実行待ちキューで管理され、I/O待ちのプロセスは待ちキューへ移される。
- コンテキストスイッチが多すぎると、切り替えのコストが増える。
- 優先度や重みはCPU時間の配分に影響するが、実際の動作はI/O待ちなどにも左右される。
- 仮想実行時間は、プロセス間の公平性を考えるための重要な指標である。

