🐍

Python 並列処理入門 ~ GIL・スレッド・プロセスまとめ ~

に公開

🐍 Python 並列処理入門 ~ GIL・スレッド・プロセスまとめ ~

この記事は自分用のメモを生成AIにまとめさせたものです。

📚 1. グローバルインタプリタロック(GIL)とは?

Python(特に CPython)には GIL(Global Interpreter Lock) という仕組みがあり、
「一度に一つのスレッドしか実行できない」 制限があります。

🔸 GILのポイント

  • メモリ管理を安全にするためのロック
  • Pythonのマルチスレッドは GILの影響で実質「擬似並列」
  • マルチスレッドで速くなるのは I/O待ちの時だけ

🔥 2. CPUバウンドと I/Oバウンド

項目 CPUバウンド I/Oバウンド
ボトルネック CPU処理速度 入出力の待ち時間
数値計算、画像処理 ファイル操作、通信
マルチスレッドの効果 ほぼ無い(GIL制限) 大きい(待ち時間に他の処理可能)
マルチプロセスの効果 非常に高い(GIL回避) 効果あり

🛠️ 3. 並列処理の比較

処理タイプ 直列(GILのみ) マルチスレッド マルチプロセス
I/Oバウンド ❌ 全順番処理(遅い) ✅ 超効果的(ほぼ並列) ✅ 効果あり(通信コストやや高)
CPUバウンド ❌ 全順番処理(遅い) ❌ GILで順番処理(効果なし) ✅ 真の並列処理(爆速)
メモリ使用 🔥 最小 🔥 小さい 💾 大きい(プロセスごとにメモリ確保)
実装の簡単さ 🍰 超簡単 🍰 簡単 🍰 やや複雑(データ共有必要)
データ共有 💬 問題なし 💬 超簡単 📦 やや面倒(Queue, Pipeが必要)

✨ 4. concurrent.futures が最近の主流!

Python 3系では concurrent.futures を使うのがオススメ!

✅ メリット

  • スレッド・プロセス両対応(文法ほぼ共通)
  • 非同期実行・並列実行が簡単に書ける
  • executor.map() でループ処理がスッキリ書ける

✅ 基本構文

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

# スレッドプール
with ThreadPoolExecutor() as executor:
    executor.map(func, iterable)

# プロセスプール
with ProcessPoolExecutor() as executor:
    executor.map(func, iterable)
  • ThreadPoolExecutor → I/Oバウンドに強い
  • ProcessPoolExecutor → CPUバウンドに強い

🚀 5. まとめ

  • Pythonのマルチスレッドは I/Oバウンド用、CPUバウンドにはほぼ意味なし(GILのせい)
  • マルチプロセスは GILの制限なし、本物の並列処理が可能!
  • 最近は concurrent.futures を使えば、簡単に並列処理が実装できる!

💡 補足

  • 本気の高速化がしたい場合は NumPyの並列処理CythonRust拡張も検討すると良い。
  • Pythonは用途に応じて「直列・スレッド・プロセス」を使い分けるのが賢いやり方。
  • コード全容を掲載したリポジトリはこちら

Discussion