Mímisbrunnr知恵の泉

← コンピュータ基礎 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:プロセスとスレッド | 関連:プロセス間通信(IPC)性能の評価とアムダールの法則

要点(BLUF)

概念 ── スケジューラは「CPUという1席の配り係」

実行可能(ready)なプロセスは複数あるのに、CPUコアは限られます。誰をどれだけ走らせるかを決めるのがスケジューラ。判断の良し悪しは指標で測ります。

これらは同時には最適化できない(トレードオフ)。だから方式が複数あります。

仕組み ── 代表的な方式

FCFS(First-Come First-Served)

到着順に最後まで走らせる(非プリエンプティブ)。単純そのもの。だが長いジョブが先頭にいると、後ろの短いジョブが延々と待たされる(コンボイ効果)。

SJF(Shortest Job First)

残り実行時間が短い順に通す。平均待ち時間を最小化することが理論的に示せる。弱点は2つ:実行時間を事前に正確に知るのは難しい(予測に頼る)こと、長いジョブが短いジョブに割り込まれ続けて飢餓になりうること。

ラウンドロビン(RR)

**タイムスライス(quantum)**ごとに強制的に次へ回す(プリエンプティブ)。全員が定期的にCPUをもらえるので公平で、対話的な応答が良い。スライスが短すぎるとプロセスとスレッドの文脈切り替えが頻発してオーバーヘッドが増え、長すぎるとFCFSに近づく。

優先度スケジューリング

各プロセスに優先度を付け高い順に。リアルタイム性が要る処理を優先できる。低優先度の飢餓対策に、待つほど優先度を上げるエイジングを併用する。

flowchart LR
    new["新規/I/O完了"] --> ready["readyキュー(実行可能な行列)"]
    ready -->|"スケジューラが選ぶ"| cpu["CPU(実行中)"]
    cpu -->|"タイムスライス終了 (RR)"| ready
    cpu -->|"I/O要求"| wait["待機(ブロック)"]
    wait -->|"I/O完了 (割り込み)"| ready
    cpu -->|"終了"| done["exit"]

具体例 ── 平均待ち時間を計算で比べる

古典例:P1=24, P2=3, P3=3(すべて時刻0着)を3方式で([[#対応ラボ]] の 02-03_scheduling.py)。

def metrics(name, finish, jobs):
    waits = [finish[p]-arr-burst for p,(arr,burst) in jobs.items()]
    print(f"{name}: 平均待ち時間 = {sum(waits)/len(jobs):.2f}")
jobs = {"P1": (0,24), "P2": (0,3), "P3": (0,3)}

実行結果(実機):

  FCFS: 平均待ち時間 = 17.00 / 平均応答時間 = 27.00
   SJF: 平均待ち時間 =  3.00 / 平均応答時間 = 13.00
RR(q=4): 平均待ち時間 =  4.33 / 平均応答時間 = 14.33

長いP1を先に通すFCFSは平均待ち17。短いP2,P3を先に通すSJFは平均待ち3で最小。RRは公平だが切替が入り中間。同じジョブ集合でも、配り方だけで体感速度が大きく変わるのがわかります。

仕組みの直観 ── なぜこの設計か

⚠️ よくある誤解・落とし穴

対応ラボ

cs-foundations-study/labs/02-03_scheduling.py(実行して上記の平均待ち時間・応答時間を確認済み)。

関連

第2章 オペレーティングシステム 目次