TL

プロセススケジューリング

1つのCPUを多数のプロセスで“代わりばんこ”に使う仕組み。誰に・どれだけCPUを渡すかを決めるのがスケジューラの仕事。

中級スケジューリングプロセスCPUOS最終更新: 2026-06-04
TL;DR要点だけ先に
  • 1.結論:CPUは一度に1つの処理しか動かせない。それを高速で切り替えて“同時に動いて見せる”のがスケジューリング。
  • 2.プリエンプティブ(途中で取り上げる)が現代OSの標準。FCFS/SJF/ラウンドロビン/優先度などの方式で“次に動かす1つ”を選ぶ。
  • 3.切り替え(コンテキストスイッチ)はタダではない。応答性(待たせない)とスループット(さばく量)はトレードオフ。

なぜ必要なのか

プロセス(実行中のプログラム)は CPU を使いたがります。でも 1コアの CPU が同時に走らせられるのは 1つだけ。プロセスが CPU を待つ列(実行可能キュー / ready queue)に並んだとき、どれを次に走らせるか を誰かが決めないといけません。

  • 全部を「順番に最後まで」やると、重い処理の後ろに並んだ軽い処理がいつまでも始まらない
  • かといって細かく切り替えすぎると、切り替えの手間ばかり食って本来の処理が進まない

このバランスを取るのがスケジューラの役目です。ちなみに「プロセス」と「スレッド」の関係や、現代OSが実際に切り替える単位については /os/process-thread/ を参照してください(実装上は スレッド単位 でスケジュールするOSが多い)。

プロセスの状態とCPUの取り合い

スケジューリングを理解する鍵は、プロセスがずっと CPU を使い続けるわけではない、という点です。プロセスは3つの状態を行き来します。

        ┌──────────┐  ディスパッチ   ┌──────────┐
        │ Ready    │ ───────────────▶ │ Running  │
        │ (待機列) │ ◀─────────────── │ (実行中) │
        └──────────┘   プリエンプト   └──────────┘
              ▲                            │
              │ I/O完了                    │ I/O要求 / sleep
              │                            ▼
        ┌─────────────────────────────────────┐
        │ Waiting / Blocked (I/O待ちなど)      │
        └─────────────────────────────────────┘

ここで重要なのは、プロセスが ディスクやネットワークの I/O を待つ間は CPU を使わない こと。その隙に別のプロセスへ CPU を回せます。だからこそ「CPUバウンド(計算中心)」と「I/Oバウンド(待ち中心)」を 混ぜて動かす と CPU を遊ばせずに済むわけです(I/O 待ちの仕組みは /os/interrupt-io/ も参照)。

プリエンプティブ と ノンプリエンプティブ

スケジューリングは「動いているプロセスを 途中で強制的に止められるか 」で大きく2種類に分かれます。

観点プリエンプティブノンプリエンプティブ
CPUの取り上げOSが途中で強制的に取り上げるプロセスが自発的に手放すまで待つ
きっかけタイマー割り込み・高優先度の到着終了・I/O要求・自発的な譲渡
応答性良い(待たせにくい)悪化しうる(長い処理に占有される)
実装の複雑さ高い(共有データの保護が必須)低い(切れ目が予測しやすい)
代表例Linux/Windows/macOS など現代の汎用OS古い協調的マルチタスク・一部の組込み

現代のデスクトップ/サーバ OS は ほぼプリエンプティブ です。定期的に発生する タイマー割り込み をきっかけに OS が制御を取り戻し、「このまま続けさせるか、別のプロセスに替えるか」を判断します。これにより、1つの暴走プロセスが CPU を独占して全体を固める事故を防げます。

“マルチタスク=同時実行”ではない

1コアでのマルチタスクは 本当に同時に動いているわけではありません。高速に切り替えて「同時に見せている」だけ(並行 / concurrency)。物理的に同時へ進むのは複数コアで実際に並列実行(parallelism)したときです。並行と並列は別物。混同に注意。

代表的なスケジューリング方式

「次に動かす1つ」をどう選ぶか。古典的なアルゴリズムを押さえると、現代の複雑なスケジューラの発想も読み解けます。

方式選び方長所短所 / 注意
FCFS(到着順)先に来た順に最後まで単純・公平で飢餓なし長い処理が先頭だと後続が待つ(コンボイ効果)
SJF(最短ジョブ優先)実行時間が短いものを先に平均待ち時間が理論上最小実行時間を事前に知れない/長い処理が飢餓に
ラウンドロビン一定時間(タイムスライス)ずつ順番に応答が良く公平スライスが短すぎると切替コスト増
優先度優先度の高いものを先に重要な処理を優先できる低優先度が飢餓に(→エイジングで救済)

FCFS(First-Come, First-Served)

来た順に並べて、各プロセスを 最後まで 実行するノンプリエンプティブな方式。仕組みは単純ですが、先頭に長い処理が来ると後ろの短い処理がまとめて待たされます(コンボイ効果)。

SJF(Shortest Job First)

残り(または必要)実行時間が 最短 のものを先に処理します。平均待ち時間を最小化できる理論的に強い方式ですが、「これからどれだけ掛かるか」を 正確には知れない のが現実の壁。過去の実績から予測する形で近似します。プリエンプティブ版は SRTF(最短残時間優先) と呼びます。

ラウンドロビン(Round Robin)

各プロセスに タイムスライス(タイムクォンタム) という持ち時間を割り当て、使い切ったら列の最後尾へ回す方式。プリエンプティブの代表で、対話的な用途に向きます。スライスの長さが肝で——

スライスが長すぎる  → FCFS に近づき、応答が悪化
スライスが短すぎる  → 切り替えばかり発生し、オーバーヘッドが増える

優先度スケジューリング

各プロセスに 優先度 を付け、高いものを先に。OS は重要なシステム処理や対話的なプロセスを優先できます。ただし優先度が低いプロセスがいつまでも回ってこない 飢餓(starvation) が起きうるので、待ち時間に応じて優先度を徐々に上げる エイジング(aging) で救済します。

優先度の落とし穴:優先度逆転

「高優先度なら必ず先に動く」と思い込むと危険。高優先度のプロセスが、低優先度のプロセスの握るロックを待ち、その低優先度が中優先度に割り込まれて進めない——という 優先度逆転(priority inversion) が起きると、高優先度が事実上止まります。火星探査機 Mars Pathfinder の不具合が有名で、対策は 優先度継承 など。排他制御の話は /os/concurrency-control/ を参照。

コンテキストスイッチ ── 切り替えはタダではない

プロセスを切り替えるとき、OS は止める側の状態(レジスタ、プログラムカウンタ、スタックポインタなど)を保存し、次に動かす側の状態を復元します。これが コンテキストスイッチ です。

[実行中:A] ── タイマー割り込み ──▶ Aの状態を保存
                                  └▶ スケジューラが次(B)を選ぶ
                                     └▶ Bの状態を復元 ──▶ [実行中:B]

この切り替え自体は 何の仕事も前に進めない純粋なオーバーヘッド。さらに切り替えで CPU キャッシュや TLB が汚れ、再び温まるまで間接的なコストもかかります。だから「細かく切り替えれば切り替えるほど良い」わけではありません。

切り替え単位はスレッド、コストはピンキリ

多くのOSが実際に切り替える単位はプロセスではなく スレッド。同じプロセス内のスレッド間切り替えは、アドレス空間(ページテーブル)を共有するぶん、別プロセスへの切り替えより軽くなります。さらに軽い切り替えとして、OS を介さずユーザー空間で切り替える非同期処理/コルーチンの考え方もあります(/programming/sync-async/)。

応答性 vs スループット ── 何を最適化するか

スケジューラに「唯一の正解」はありません。何を良しとするかは用途しだいで、しかも複数の指標は 同時に最大化できないトレードオフ の関係にあります。

指標意味重視する場面
応答時間 / レイテンシ要求してから反応が返るまでの速さ対話的UI・ゲーム・Webサーバ
スループット単位時間にさばける処理の量バッチ処理・ビルド・データ集計
公平性どのプロセスにも均等に機会が回るかマルチユーザー・共有サーバ
CPU使用率CPUを遊ばせず使い切れているか計算資源を絞り切りたい全般

例えばタイムスライスを短くすると、各プロセスがすぐ順番を得られて 応答は良く なりますが、切り替えが増えて スループットは落ちます。逆に長くすればスループットは上がるが対話の反応は鈍る。現実のOSは、対話的なプロセスには短く・計算中心のプロセスにはまとめて時間を渡す、といった 動的な調整(マルチレベルフィードバックキュー、Linux の CFS / EEVDF など)でこのバランスを取っています。

“速いCPU”が体感を決めるとは限らない

体感のキビキビ感は CPU の生クロックだけでなく スケジューラの方針 に大きく左右されます。重いビルド中でも入力が引っかからないのは、OS が対話的プロセスを優先して短く回しているから。逆に方針が悪ければ高性能CPUでも“もっさり”します。

まとめ ── どう選ぶか

  • 待たせたくない(対話・サーバ) → プリエンプティブ+短めスライスで 応答性 を優先
  • とにかく量をさばきたい(バッチ・ビルド) → 切替を減らして スループット を優先
  • 重要処理を優先しつつ全員に機会を → 優先度+エイジング、あるいはマルチレベルフィードバックキュー
  • 共通の鉄則:切り替えはタダではない。応答性とスループットは引っ張り合うので、用途に合わせて配分を決める

スケジューリングは「限られた CPU 時間を誰にどう配るか」という資源配分の問題。メモリの配り方(/os/memory-management/)と並ぶ、OS の中核的な仕事のひとつです。

OS Article

プロセススケジューリングを実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

スケジューリング

比較で見る軸

難易度: intermediate / カテゴリ: OS / タグ数: 4

導入後に効く点

プリエンプティブ(途中で取り上げる)が現代OSの標準。FCFS/SJF/ラウンドロビン/優先度などの方式で“次に動かす1つ”を選ぶ。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
intermediate
カテゴリ
OS
タグ数
4

判断チェックリスト

  • 自社の用途が「スケジューリング / プロセス」に近いか確認する。
  • 強みである「結論:CPUは一度に1つの処理しか動かせない。それを高速で切り替えて“同時に動いて見せる”のがスケジューリング。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

スケジューリングプロセスCPUOSスケジューリングプロセスCPUOS
参考: 公式情報