コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
スレッドとプロセスの違い
スレッドとプロセスの違い
このレッスンで分かること
- スレッドは 同じプロセス内のメモリを共有する実行単位 で、プロセスより軽量です
- プロセスは強い分離、スレッドは速い共有という対比で覚えると整理しやすくなります
- スレッドのメリットは並列処理ですが、共有ゆえに データ競合 のリスクも増えます
スレッドとプロセスの違い とは
スレッドとプロセスの違い。本レッスンでは、スレッドとプロセスの違い の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
スレッドとは何か
プロセスはメモリ空間ごと別世界に分かれます。一方、スレッドは 1 つのプロセスの中で コードとヒープを共有しつつ、スタックとレジスタだけ別々 に持つ実行単位です。プロセスがアパートだとすれば、スレッドは同じ部屋に住む同居人で、家具(ヒープ)は共有、個人のノート(スタック)は別、というイメージです。
プロセスとスレッドの比較
| 観点 | プロセス | スレッド |
|---|---|---|
| メモリ | 完全に別 | コード・ヒープ共有 |
| 通信コスト | IPC が必要 | 変数の代入で済む |
| 生成コスト | 高い | 低い |
| 分離度 | 強い(落ちても他に波及しない) | 弱い(1 つ落ちるとプロセス全体停止) |
| 同期 | 不要なことが多い | mutex 等が必須 |
図解
1 つのプロセスに複数スレッドが共存し、ヒープを共有します。プロセス間のやり取りはパイプやソケットなどの IPC を経由します。
具体例 (Python)
Python
import threading
import time
counter = 0
def worker():
global counter
for _ in range(100_000):
counter += 1 # 共有変数を更新
threads = [threading.Thread(target=worker) for _ in range(4)]
for t in threads: t.start()
for t in threads: t.join()
print(counter) # 期待: 400000, 実際は ?counter += 1 は実は「読み出し → +1 → 書き戻し」の 3 ステップで、スレッドが割り込むと値が失われます。これを データ競合(race condition) と呼びます。ロックを使うと解決できます。
Python
lock = threading.Lock()
def worker_safe():
global counter
for _ in range(100_000):
with lock:
counter += 1いつスレッドを使うか
スレッドが活きるシーン例は下記のとおりです。
- I/O 待ちの間に他の仕事を進めたい(ファイル DL、DB 問合せの並列)
- 重い計算を CPU コア数だけ並列に走らせたい
- GUI でユーザー入力を受けつつバックグラウンドで作業したい
逆にプロセスが向くのは下記です。
- セキュリティ境界が必要(ブラウザのタブ別プロセス)
- 1 つのバグで全体を巻き込みたくない(Apache の prefork モデル)
- 言語に GIL があり並列計算でスレッドが効かない(CPython の場合)
トレードオフ
- スレッドは共有が速い反面、バグの再現が難しい という代償を払います。タイミングに依存する不具合は最悪のテスト対象です
- CPython の GIL(Global Interpreter Lock)は 1 プロセス内で 1 スレッドしか Python バイトコードを実行できないようにする錠前で、CPU バウンドな処理ではスレッドが速くなりません。代わりに
multiprocessingでプロセスを並列化します - Java や Go ではスレッドが本物の並列実行を提供しますが、それでも適切な同期は必要です
よくある誤解
- 「スレッドを増やせば速くなる」は誤りで、CPU コア数を超えると コンテキストスイッチ で逆に遅くなります
- 「Go の goroutine はスレッド」も半分正解で、Go ランタイムが少数の OS スレッド上に何千もの goroutine を多重化する M:N モデル です
やってみよう
ps -eLf を実行すると、プロセスとスレッド(LWP 列)の両方が見えます。Chrome や VS Code といった現代のアプリは 1 プロセスで数十~数百のスレッドを持つことが珍しくありません。
よくある質問
Q. プロセスとスレッドの違いは?
A. プロセスは独立したメモリ空間を持つ実行単位、スレッドは同じプロセス内でメモリを共有する実行単位です。プロセスの切り替えは重く、スレッドは軽量です。マルチコア活用にはスレッドが向き、堅牢な分離にはプロセスが向きます。
Q. スレッドが多すぎるとどうなりますか?
A. コンテキストスイッチのオーバーヘッドで全体性能が下がります。CPU バウンドな処理ならコア数程度、I/O バウンドならその数倍が適正です。スレッドプール(ExecutorService、ThreadPoolExecutor)で上限を制御すると安定します。
Q. プロセス間で通信するには?
A. パイプ、ソケット、共有メモリ、メッセージキューなどがあります。同一マシンならソケット(UNIX domain socket)や共有メモリが高速で、分散システムなら gRPC、HTTP、Kafka などのメッセージング基盤が定番です。
次のレッスン
次は コンテキストスイッチ で、スレッドとプロセスの違い を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- スレッドとプロセス の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. スレッドとプロセス とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン