コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
プロセスとは
プロセスとは
このレッスンで分かること
- プロセスは 「実行中のプログラム」 をカーネルが管理する単位です
- 各プロセスは独立した仮想メモリ空間、PID、ファイルディスクリプタ表、優先度などを持ちます
- 親子関係(fork で複製、exec で中身を入れ替え)が OS の基本動作モデルです
プロセス とは
プロセスとは。本レッスンでは、プロセス の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
プロセスの構成要素
プログラムはディスク上のバイナリです。そのバイナリをカーネルがメモリに読み込み、実行を開始した瞬間に プロセス になります。1 つの実行ファイル(例 python)から、同時に何個ものプロセスを立ち上げることができます。
カーネルは各プロセスについて下記の情報を プロセス制御ブロック(PCB / task_struct) に保持します。
| 項目 | 説明 |
|---|---|
| PID | プロセス ID(一意な整数) |
| 親 PID | 自分を起動したプロセス |
| 仮想メモリ空間 | コード・データ・スタック・ヒープのレイアウト |
| ファイルディスクリプタ | 開いているファイルやソケット |
| 実行状態 | running、sleeping、stopped、zombie |
| 優先度 / nice 値 | スケジューラ用 |
| シグナルマスク | 無視する/待ち受けるシグナル一覧 |
プロセスのライフサイクル
fork で生まれ、CPU を割り当てられたら running、I/O を待っているときは waiting、終了した直後に親が wait するまでの一時状態を zombie と呼びます。ps で Z と表示されたらこの状態です。
具体例
シェルから ls を起動する内部動作は下記のとおりです。
c
pid_t pid = fork(); // 子プロセスを作る
if (pid == 0) {
// 子側:自分を ls に入れ替える
execve("/bin/ls", (char *[]){"ls", NULL}, environ);
} else {
// 親側:子の終了を待つ
int status;
waitpid(pid, &status, 0);
}fork の戻り値は 親には子の PID、子には 0 が返ります。子は execve で別プログラムに変身し、親は waitpid で終了通知を受け取ります。
プロセスを観察する
ターミナル
ps -ef | headプレーンテキスト
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:30 ? 00:00:01 /sbin/init
root 412 1 0 09:30 ? 00:00:00 /usr/sbin/sshd -D
alice 1024 1023 0 09:31 pts/0 00:00:00 -bash
alice 2048 1024 0 09:32 pts/0 00:00:00 ps -efPPID 列に注目すると、ps の親は bash、bash の親は sshd、sshd の親は init(PID 1)という親子関係が読み取れます。すべてのプロセスは最終的に PID 1 を祖先に持つツリーを構成しています。
トレードオフ
- プロセス生成(fork)はメモリ空間の複製を伴うため、スレッド生成より重いです。Web サーバーが「リクエストごとに fork」する古典モデルから「ワーカープールでスレッドを使い回す」モデルへ移行したのはこのコストが理由です
- 分離が強い分、プロセス間のデータ共有は IPC(パイプ、共有メモリ、ソケット) が必要で、設計上のオーバーヘッドが増えます
よくある誤解
- 「プログラム = プロセス」ではありません。プログラムはディスク上の 静的なファイル、プロセスは実行中の 動的なインスタンス です
- 「fork したら CPU を 2 倍使う」も誤解で、Copy-on-Write のおかげで実際にメモリが複製されるのは書き込みが発生したページだけです
- 「PID は再利用されない」も誤解で、
/proc/sys/kernel/pid_max(Linux なら通常 4 万 ~ 4 百万)の上限を超えると 回り込んで再利用 されます
やってみよう
別のターミナルで sleep 60 を実行し、元のターミナルで pgrep sleep で PID を取り、cat /proc/<PID>/status を覗いてみてください。State、PPid、VmSize など、カーネルが管理している生のプロセス情報が見られます。
よくある質問
Q. プロセスとスレッドの違いは?
A. プロセスは独立したメモリ空間を持つ実行単位、スレッドは同じプロセス内でメモリを共有する実行単位です。プロセスの切り替えは重く、スレッドは軽量です。マルチコア活用にはスレッドが向き、堅牢な分離にはプロセスが向きます。
Q. スレッドが多すぎるとどうなりますか?
A. コンテキストスイッチのオーバーヘッドで全体性能が下がります。CPU バウンドな処理ならコア数程度、I/O バウンドならその数倍が適正です。スレッドプール(ExecutorService、ThreadPoolExecutor)で上限を制御すると安定します。
Q. プロセス間で通信するには?
A. パイプ、ソケット、共有メモリ、メッセージキューなどがあります。同一マシンならソケット(UNIX domain socket)や共有メモリが高速で、分散システムなら gRPC、HTTP、Kafka などのメッセージング基盤が定番です。
次のレッスン
次は スレッドとプロセスの違い で、複数の処理を1プロセス内で並行させる仕組みを学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- プロセス の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. プロセス とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン