ソフトウェアとOS — 部品を動かし、アプリを支える

概要 — まず全体をつかむ

初級ではOSを「店長(世話役)」と捉えました。中級では、カーネルの中身と、資源管理の仕組みを見ます。

詳細 — 1段階ずつ追う

OSの中心=カーネル

OSの核がカーネル。アプリ(ユーザー空間)と、ハードを直接触る領域(カーネル空間)を分け、境界越しに安全にやり取りします。

  • システムコール — アプリがカーネルに処理を頼む窓口
  • プロセス/スレッド — 実行単位。プロセスは独立、スレッドは同一プロセス内で並行。プロセスには実行/待機/レディなどの状態があり、切り替えながら進む
  • ドライバ — 各ハードを操作するためのカーネルの部品
アニメーション『プロセスとスレッド』を開く
プロセスA独立したメモリ空間スレッド1スレッド2スレッド3共有メモリ(ヒープ・グローバル変数など)↑ 同一プロセス内のスレッドが共有プロセスB独立したメモリ空間スレッド1スレッド2スレッド3共有メモリ(ヒープ・グローバル変数など)↑ 同一プロセス内のスレッドが共有隔離互いに見えないプロセスは独立(メモリを隔離)/スレッドは同一プロセス内でメモリを共有

登場人物メモ:

  • ※1 ユーザー空間/カーネル空間 — 権限を分けた2つの領域
  • ※2 スケジューラ — どのプロセスにCPUを、いつ渡すかを決める係
この部分をもっと深く(上級
  • 構造 — モノリシック(Linux)/マイクロカーネル。ドライバや機能をどこに置くか
  • 特権レベル(リング) — ユーザーモードとカーネルモードを分け、境界越えはトラップ(システムコール)
  • コンテキストスイッチ — プロセス/スレッドを切り替える。レジスタ退避・TLBフラッシュなどのコストがある
やさしく言うと(初級
  • ハードウェア — 体(CPU・メモリ・ストレージなどの部品)
  • ソフトウェア — 動き(何をするかの指示・プログラム)
  • OS — 全体の世話役。ハードを管理し、アプリに資源を配る

料理店でいえば、OSは店長(司会・仲介)。誰がコンロ(CPU)をいつ使うか、材料(メモリ)をどう配るかを采配します。

登場人物メモ:

  • ※1 アプリ — 個別の仕事をするソフト(ブラウザ・表計算など)
  • ※2 プロセス — 実行中のアプリ(動いている状態の1つ)

資源をどう配るか

  1. CPUスケジューリング — 多数のプロセスに、CPU時間を細切れ(タイムスライス/時分割)で順に割り当てる。これで見かけ上の同時実行=マルチタスクを実現する
  2. メモリ管理仮想メモリで各プロセスに広い空間を見せ、足りなければスワップ
アニメーション『仮想メモリ(見せかけの広い空間)』を開く
仮想メモリ — 広い仮想アドレスを、狭い物理メモリ+ストレージへ対応づけるプロセスが見る仮想アドレス空間(広い)仮想ページ V0仮想ページ V1仮想ページ V2仮想ページ V3仮想ページ V4仮想ページ V5⋮ さらに続く(見かけ上とても広い)ページテーブル(対応表)V0実メモリ F2V1実メモリ F0V2スワップへ退避V3実メモリ F3V4スワップへ退避V5実メモリ F1実メモリへ足りない分は退避(スワップ)実際の物理メモリ(狭い)フレーム F0(V1)フレーム F1(V5)フレーム F2(V0)フレーム F3(V3)スワップ(ストレージへ退避)V2V4当面使わないページを退避(遅い)広く見せかけ、足りない分はストレージで代用(スワップ)。使いすぎると激遅になる
  1. ファイルシステム — ストレージ上のデータを、名前とディレクトリで扱えるようにする
  2. 入出力 — ドライバ経由で周辺機器を操作する
この部分をもっと深く(上級
  1. スケジューラ — 公平性(LinuxのCFS。カーネル6.6以降は後継のEEVDFに刷新)や優先度、リアルタイム制約で「次に走らせる」を決める
  2. ページング — メモリをページ単位で管理。ページテーブルで仮想→物理を変換
  3. TLB — 変換結果をキャッシュして高速化。ミスすると遅い
  4. デマンドページング — 使う瞬間にページを割り当て、足りなければ退避(スワップ)
  5. コピーオンライト — fork時などは共有し、書き込み時に初めて複製
やさしく言うと(初級
  1. ハードを管理 — CPU・メモリ・ストレージ・周辺機器をまとめて面倒を見る
  2. 資源を配る — どのアプリにCPUの時間・メモリの場所を渡すか采配
  3. 仲介する — アプリの「画面に出して」「ファイルを開いて」を受けて、ハードに橋渡し
  4. 守る — アプリどうしが干渉しないよう隔離する

だからアプリは、ハードの細かい違いを気にせず作れます。

守りと分離

  • 保護 — 権限(ユーザー空間)を分け、アプリがカーネルやハードを直接壊せないようにする
  • 隔離 — プロセスごとにメモリ空間を分け、干渉を防ぐ
  • 並行制御 — 共有資源はロック等で守る(不備はデッドロックの原因)
この部分をもっと深く(上級
  • 同期プリミティブ — ミューテックス/セマフォ/スピンロック/futex。粒度と競合の設計
  • 割り込みとDMA — 入出力はポーリングでなく割り込みで、大量転送はDMAでCPUを介さず
  • コンテナnamespace+cgroups でカーネルを共有しつつ隔離(VMより軽量)
  • ファイルシステム — ジャーナリングで障害時の整合を守る、ページキャッシュで高速化
やさしく言うと(初級
  • 共通の窓口 — アプリはOSにお願いするだけ。機種ごとの違いをOSが吸収する
  • 同時に動かす — 複数アプリを、順番に少しずつ動かして「同時」に見せる
  • 安全 — 1つのアプリの暴走が、他やハードを壊さないようにする

⚠️ うまくいかないとき

  • スワップ多発 — 仮想メモリの使いすぎで、ストレージ待ちが増え激遅に
  • デッドロック — 複数プロセスが互いのロックを待って止まる
  • メモリリーク — 解放し忘れでメモリを食い潰す
  • ゾンビプロセス — 親が終了状態を回収せず、プロセス表にPID枠だけが残る(CPU・メモリはほぼ消費しない)
  • 暴走プロセス — 無限ループや解放漏れで、CPU・メモリを占有し続ける
この部分をもっと深く(上級
  • スラッシング — スワップが多発し、処理よりページ入替に時間を食う
  • 優先度逆転 — 低優先度がロックを握り、高優先度が待たされる(優先度継承で対処)
  • ロック競合/デッドロック — 粒度が粗い・順序が不整合
  • コンテキストスイッチ過多 — スレッド乱立で切替コストが支配的に
  • メモリ順序の落とし穴 — ロックレス並行処理での可視性・並べ替え
やさしく言うと(初級
  • フリーズ — あるプロセスが暴走し、応答しなくなる
  • アプリが落ちる — そのプロセスだけ強制終了される(OSが他を守る)
  • 重い — メモリやCPUの取り合い(資源不足)

関連する知識

理解度チェック

そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。

1. アプリがOSに「ファイルを開く」「画面に出す」などを頼むための窓口を何と呼ぶ?

2. 実メモリより大きく見せかけ、足りない分をストレージで代用する仕組みは?

3. CPUが1個でも複数のプロセスが同時に動いて見えるのは、CPU時間を細切れにして順に割り当てているからです。この方式の呼び方はどれ?

4. 親プロセスが終了状態を回収せず、プロセス表にPIDの枠だけが残ってしまう状態はどれ?

5. 複数のプロセスが互いに相手の握るロックの解放を待ち合い、どちらも進めなくなる状態はどれ?

6. OSが「あるアプリの暴走が他のアプリやカーネルを直接壊さない」ようにするため、プロセスごとにメモリ空間を分ける仕組みを何と呼ぶ?

7. プリンタやディスクなど、各ハードウェアを操作するためのカーネルの部品を、カタカナで何と呼ぶ?

8. プログラムが確保したメモリを解放し忘れ、使用メモリが増え続けて食い潰していく不具合を、カタカナで何と呼ぶ?