【比較】プロセスとスレッドの違い¶
概要¶
「プロセス」と「スレッド」は、OS が並行処理を実現するときの実行単位ですが、メモリ空間の扱いが根本的に異なります。プロセスは独立したアドレス空間(メモリ)を持つ実行中のプログラムであり、スレッドはそのプロセス内部で動く軽量な実行の流れです。1つのプロセスは少なくとも1つのスレッド(メインスレッド)を持ち、複数スレッドを生成できます。
両者が混同されやすいのは、どちらも「並行して動かす手段」として語られるためです。しかし「メモリを共有するか/隔離するか」という1点を押さえると、性能・安全性・障害分離の議論がすべて整理できます。本記事では POSIX threads や CPython の公式仕様に沿って、共有されるもの・されないものを正確に区別します。
詳細比較¶
| 項目 | プロセス (Process) | スレッド (Thread) |
|---|---|---|
| アドレス空間 | 独立。各プロセスが固有の仮想メモリ空間を持つ | 同一プロセス内のスレッド間で共有(グローバル変数・ヒープを共有) |
| スレッド固有のもの | (プロセス自体が単位) | スタック(自動変数)、スレッドID、errno、シグナルマスク、スケジューリング属性は各スレッド固有 |
| ファイルディスクリプタ | プロセスごとに独立 | 同一プロセス内で共有(同じ open ファイルを参照) |
| 生成・切り替えコスト | 重い(メモリ空間の確保、ページテーブル等) | 軽い(メモリ空間を共有するため) |
| 通信手段 | プロセス間通信(IPC): パイプ、ソケット、共有メモリ、メッセージキュー等が必要 | 共有メモリを直接読み書き(ただし排他制御が必須) |
| 障害分離 | 高い。1プロセスがクラッシュしても他プロセスは原則影響を受けない | 低い。1スレッドが不正メモリアクセス等で落ちるとプロセス全体が巻き添えになり得る |
| 並列実行(マルチコア) | 各プロセスは独立して複数コアで真に並列実行できる | OS スレッドは複数コアで並列実行可能(言語ランタイムの制約が別途加わる場合あり) |
POSIX threads の仕様では、同一プロセス内のスレッドはグローバルメモリ(データ・ヒープ)、open ファイルディスクリプタ、シグナルハンドラの割り当て、ユーザー/グループID などプロセス全体の資源を共有し、一方でスタック・スレッドID・errno・シグナルマスクは各スレッド固有です。この「共有と固有の線引き」がスレッドプログラミングの安全性設計の出発点になります。
よくある誤解¶
-
「スレッドはメモリを共有しないので速い」は誤り。 逆です。スレッドが軽量なのはメモリ空間を共有するためにプロセスのような独立アドレス空間の確保が不要だからです。共有しているからこそ、複数スレッドが同じ変数を同時更新するとデータ競合が起き、ミューテックス等の排他制御が必要になります。
-
「Python のスレッドは GIL があるから常に無意味」は誤り(過度な一般化)。 GIL(グローバルインタプリタロック)は CPython という特定実装の事情であり、OS スレッドやスレッドという概念一般の制約ではありません。Java や C++ のスレッドにはこの制約はありません。さらに CPython でも、I/O 待ち(ネットワーク・ファイル)の間は GIL が解放されるためスレッドで並行化の効果が出ますし、GIL を撤廃する取り組みも進んでいます。Python 3.13 で実験的に導入された free-threaded(GIL なし)ビルドは、Python 3.14(2025年10月)以降 PEP 779 に基づき公式サポート(ただし既定では無効でオプトイン)となっています。「CPU バウンドな純 Python 計算を CPython の標準ビルドでマルチコア並列化したい」場合に限り効果が出にくい、というのが正確な理解です。
-
「マルチスレッドは必ずマルチプロセスより速い」も誤り。 切り替えコストはスレッドが安いものの、共有状態のロック競合が増えると逆にスケールしません。障害分離やメモリ隔離が必要な場面ではプロセス分割の方が総合的に優れることが多くあります。
実務での選び分け¶
- 障害を分離したい/クラッシュの巻き添えを避けたい → プロセス分割(例: ブラウザのタブごとのプロセス、ワーカープロセスモデル)。
- 大量の軽量タスクを低コストで並行させたい/状態を密に共有したい → スレッド(例: サーバの同時接続処理、UI のバックグラウンド処理)。
- CPython で CPU バウンドな計算を並列化したい →
multiprocessingでプロセスを分ける(各プロセスが独立した GIL を持つため真の並列が可能)。I/O バウンドなら標準のスレッドで十分効果が出る。 - スレッドを使うと決めたら排他制御を設計の最初に組み込む → 共有データへのアクセスは必ずロック/不変データ/メッセージパッシングのいずれかで保護する。
ひとことまとめ¶
プロセスは「独立したメモリ空間を持つ隔離された実行単位」、スレッドは「メモリを共有する軽量な実行の流れ」であり、隔離(安全・障害分離)を取るか共有(軽量・密連携)を取るかが選択の本質です。
出典・参考¶
- pthreads(7) — Linux manual page (man7.org) — スレッド間で共有される資源と各スレッド固有の属性の定義
- Thread State and the Global Interpreter Lock — Python C API 公式ドキュメント — GIL とスレッドごとの PyThreadState
- PEP 703 – Making the Global Interpreter Lock Optional in CPython — free-threaded ビルドの仕様
- Python support for free threading — Python HOWTO 公式ドキュメント — Python 3.14 で PEP 779 に基づき公式サポート(既定無効・オプトイン)となった free-threaded ビルドの解説
- threading — Thread-based parallelism — Python 公式ドキュメント — Python スレッドと GIL の挙動