プロセスとスレッド
OS のプロセスとスレッドの違い、およびプログラムの並行実行モデル
OS並行処理
プロセスとスレッドとは
プロセスは OS が管理するプログラムの実行単位で、独立したメモリ空間を持つ。スレッドはプロセス内の実行単位で、同じメモリ空間を共有する。
比較
| 観点 | プロセス | スレッド |
|---|---|---|
| メモリ | 独立 (隔離) | 共有 |
| 生成コスト | 高い | 低い |
| 通信 | IPC (パイプ、ソケット) | 共有メモリ (直接) |
| 障害の影響 | 他プロセスに影響しない | 同一プロセス内の全スレッドに影響 |
| 例 | Chrome のタブ | Java のスレッド |
プロセス A (メモリ空間 A) プロセス B (メモリ空間 B)
├── スレッド 1 ├── スレッド 1
├── スレッド 2 └── スレッド 2
└── スレッド 3
↑ 同じメモリを共有 ↑ A とは独立したメモリ
Node.js のモデル
Node.js はシングルプロセス・シングルスレッド (メインスレッド) + イベントループで動作する。
メインスレッド: [イベントループ] → I/O を非同期で処理
Worker Threads: CPU バウンドな処理を別スレッドで実行
child_process: 別プロセスでコマンドを実行
cluster: 複数プロセスでリクエストを分散
| 方法 | 用途 |
|---|---|
| イベントループ | I/O バウンド (API 呼び出し、DB) |
| Worker Threads | CPU バウンド (画像処理、暗号化) |
| cluster | マルチコア活用 (HTTP サーバー) |
Lambda のプロセスモデル
Lambda は 1 リクエスト = 1 実行環境 (プロセス) で処理する。同時実行は複数の実行環境 (プロセス) で並列処理される。
リクエスト 1 → 実行環境 A (プロセス A)
リクエスト 2 → 実行環境 B (プロセス B)
リクエスト 3 → 実行環境 C (プロセス C)
データ競合
スレッド間でメモリを共有するため、同時アクセスでデータ競合が発生する。
// ❌ データ競合 (Node.js の SharedArrayBuffer)
// スレッド A: counter++ (read → increment → write)
// スレッド B: counter++ (read → increment → write)
// 結果: 2 ではなく 1 になる場合がある
// ✅ Atomics で安全にアクセス
Atomics.add(sharedArray, 0, 1);
コンテナとプロセス
Docker コンテナは通常 1 プロセスを実行する (PID 1)。複数プロセスが必要な場合はサイドカーパターンで別コンテナに分離する。
基礎から学ぶなら関連書籍が手がかりになる。