投稿

[今さら始める Python マスター #16] マルチプロセスと並列処理

Pythonのthreading、multiprocessing、concurrent.futuresを使い分けるための基本を学びます。

[今さら始める Python マスター #16] マルチプロセスと並列処理

並列処理が必要な場面

大量のファイル処理、複数APIの呼び出し、重い計算などでは、処理を分けて進めることで時間を短縮できる場合があります。

スレッド

以下は並列実行の枠組みだけを示しています。fetch_urlとurls、プロセス版のcalculateとvaluesはこのページに定義がないため、処理する関数と入力列を先に用意します。まず逐次実行した結果と同じ値が返るかを比べてから、時間を測りましょう。

I/O待ちが多い処理にはスレッドが向いています。

1
2
3
4
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor() as executor:
    results = list(executor.map(fetch_url, urls))

プロセス

プロセス版をスクリプトへ組み込むときは、子プロセスから読み込める場所にcalculateを定義し、実行開始部分をif __name__ == "__main__":の中へ置きます。新しいプロセスがモジュールを読み込んだときに、同じ起動処理を繰り返さないための構成です。

CPUを多く使う計算では、マルチプロセスを検討します。

1
2
3
4
from concurrent.futures import ProcessPoolExecutor

with ProcessPoolExecutor() as executor:
    results = list(executor.map(calculate, values))

使い分け

ネットワーク待ちはスレッド、CPU計算はプロセス、非同期I/Oはasyncioが候補になります。

今日のゴール

並列処理は便利ですが、複雑さも増えます。まずはI/O待ちとCPU計算の違いを理解し、用途に合う方法を選びましょう。

この投稿は投稿者によって CC BY 4.0 の下でライセンスされています。