FE EXAM

OSのプロセス(実行の単位とメモリ空間)

「実行中のプログラム」がどんなメモリ構造を持ち、OSがどう生成・終了・切替するかを可視化します。

PROCESS SIMULATOR
コード
データ
ヒープ
スタック
現在のシナリオ
プロセスのライフサイクル
プロセスが生成され、メモリ空間を持ち、実行され、終了するまでの一生を追います。
表示中のプロセス
1
シナリオ
ステップ1 / 8
STEP 1/8プロセスが生成されるシェルや別プロセスからの依頼で、OSがプロセスを生成。OSはまずプロセス管理のための情報(PCB)を作成する。
解説

📌
プロセスとは — 実行中のプログラム

実行ファイルapp.exe / a.out起動プロセス実行中の姿

プロセス(Process)は「実行中のプログラム」のことです。ディスク上にあるただのファイル(例: app.exe)を起動した瞬間、OSはそれをメモリに展開し、独自の状態を持つプロセスを作ります。

プログラムとプロセスの違いは、「料理レシピ」と「実際に作っている料理」に例えられます。レシピ(プログラム)は紙の上で静的ですが、実際に作っている料理(プロセス)は調理中で動的で、独自の状態(材料の量・火加減)を持ちます。同じレシピから複数の料理を同時に作れるのも同じです(同じプログラムから複数プロセスを起動できる)。

上のツールで「プロセスのライフサイクル」を ▶ 自動再生すると、プロセスが生成・実行・終了する一連の流れを動きで確認できます。

📌
プロセスのメモリ構造(4つの領域)

コード(命令)読み取り専用データ(グローバル変数)初期値ありヒープ(動的確保)↓ 伸びるスタック(関数呼出)↑ 伸びる

プロセスのメモリ空間は4つの領域に分かれています。それぞれの役割を押さえておきましょう。


コード領域(テキスト):機械語の命令が並ぶ場所。読み取り専用なのでバグで書き換わる事故がない
データ領域:グローバル変数や静的変数を保管。プログラム開始時にサイズが決まる
ヒープ領域:実行中に動的に確保するメモリ。malloc() / new で取られる
スタック領域:関数呼び出しで使う。ローカル変数や戻りアドレスが入る

上のツールのステップ2〜3で、コード・データが先に割り当てられ、続いてヒープとスタックが用意される様子が見られます。ヒープとスタックは互いに向き合うように伸びる(衝突するとスタックオーバーフロー)のがポイントです。

📌
PCB — プロセスを管理する「カルテ」

PCBPID (プロセス番号)状態 (実行/待機/...)レジスタの値優先度メモリ管理情報

OSは各プロセスについてPCB(プロセス制御ブロック / Process Control Block)という「カルテ」を持っています。プロセスの状態を一元管理するための情報パッケージです。

PCBに含まれる代表的な情報:
PID:プロセスを識別する一意の番号
状態:実行中 / 待機 / 準備完了 など
レジスタ値:プログラムカウンタや汎用レジスタの現在値
優先度:スケジューリングに使う値
メモリ管理情報:そのプロセスが使うメモリ範囲

コンテキストスイッチ(後述)のとき、CPUはこのPCBを退避・復元することで「中断したところから再開」できます。PCBはプロセスの記憶と言ってもよいでしょう。

📌
プロセスの独立性 — 1つが落ちても他は無事

プロセス1✓ 正常稼働独自メモリプロセス2💥クラッシュ

プロセスは互いに完全に独立しています。各プロセスは自分のメモリ空間しか見られないため、1つのプロセスがバグでクラッシュしても他のプロセスにはまったく影響しません。

この独立性は、「集合住宅で隣の部屋」のような関係です。隣の部屋(プロセス2)で火事が起きても、適切な壁(OS のメモリ保護機構)があれば自分の部屋(プロセス1)は無事。アパートの管理人(OS)は壁の管理に責任を持ち、住人同士が勝手に壁を越えられないよう監視します。

上のツールのステップ7で、プロセス2がクラッシュしてもプロセス1が動き続ける様子を確認できます。これがプロセスを使う最大のメリットで、Webブラウザのタブごとに別プロセスにする設計(Chrome 等)もこの独立性を活かしています。

📌
コンテキストスイッチ — プロセスの「席替え」

P1 実行→ 退避切替→ 復元P2 実行PCB に状態保存 → 別のPCBから状態復元この切替に時間がかかる(重い)

CPUは一度に1つのプロセスしか実行できません。複数プロセスが同時に動いて見えるのは、OSが高速で切り替えているからです。この切替をコンテキストスイッチと呼びます。

コンテキストスイッチで OS が行うこと:
状態の退避:今動いているプロセスのレジスタ値を PCB に書き込む
状態の復元:次に動かすプロセスの PCB からレジスタ値を読み出す
メモリ管理切替:仮想メモリのページテーブルを差し替える

プロセスのコンテキストスイッチは重いのがネックです。メモリ管理情報まで全部入れ替えるため、数マイクロ秒〜数十マイクロ秒のオーバーヘッドが発生します(後述のスレッドはこれが軽い)。

📌
fork — プロセスを「コピーで生む」

親プロセスfork()→ コピー親 (続行)子 (新規)

Unix 系 OS(Linux / macOS)でプロセスを増やす基本は fork() システムコールです。親プロセスを丸ごとコピーして子プロセスを作ります。

fork() の特徴:
・親と子は別々のメモリ空間を持つ(コピー直後は内容が同じ)
・fork() の返り値で親子を区別:親には子のPID、子には 0 が返る
・直後に exec() を呼んで別プログラムに置き換える「fork-exec パターン」が一般的

Windows では fork ではなく CreateProcess() という別のAPIを使いますが、「新しいプロセスを作る」という目的は同じです。「fork は親プロセスのコピーを作る」と覚えておくとよいでしょう。

📌
プロセスの3つの状態と遷移

実行可能(待ち行列)実行中(CPU 使用中)待機中(入出力待ち)割り当て切り上げ入出力発生入出力完了

プロセスは常にどれか1つの状態にあり、OSの管理のもとで状態が切り替わります。3つの主な状態を押さえておきましょう。
実行可能状態(準備完了):CPU を割り当ててもらうのを待っている状態。「待ち行列(=順番待ちの列)」に並んでいるイメージ
実行中(実行状態):CPU を使って命令を処理している状態。1つの CPU につき同時に1プロセスだけ
待機中(ブロック状態):ディスク読み込みやキーボード入力など、外部の結果を待っている状態

なぜ3つの状態に分けるのか。それはCPUを無駄なく使うためです。入出力の待ち時間はとても長い(CPU の速度と比べると数十万倍以上)ので、待っているプロセスに CPU を持たせ続けると大きな無駄になります。待機中にCPUを別のプロセスへ回すことで、CPUを休ませずにたくさんの仕事をこなせるようになります。

身近な例では、レジ待ちの行列(実行可能)→ レジ精算中(実行中)→ カードの処理を待つ(待機中)のような流れに似ています。カード処理の間、お客さん(プロセス)はレジ(CPU)を占有せず、別のお客さんが使えるようになると考えるとイメージしやすいです。

練習問題

🎯
基本情報技術者 練習問題

Q1.プロセスのメモリ構造に含まれない領域はどれか。
A.コード領域
B.スタック領域
C.ヒープ領域
D.カーネル領域
Q2.プロセスが異常終了したとき、他のプロセスへの影響として正しいものはどれか。
A.同じCPUを使う他プロセスもすべて停止する
B.他のプロセスは影響を受けず動き続ける
C.同じファイルを開いていた他プロセスは強制終了する
D.OS全体がクラッシュする
Q3.fork() システムコールの動作として正しいものはどれか。
A.実行中のプロセスを終了させる
B.別のプログラムを起動して現在のプロセスを置き換える
C.現在のプロセスを複製して子プロセスを作る
D.プロセスにメモリを追加で確保する

関連コンテンツ