---
slug: "プロセスプールを使って並列処理を簡単に書く"
title: "プロセスプールを使って並列処理を簡単に書く"
description: "Python の `multiprocessing.Pool` (ProcessPoolExecutor) を使って、CPU バウンドな処理を簡単に並列化する書き方とよくあるハマりどころ。"
url: "https://www.ytyng.com/blog/プロセスプールを使って並列処理を簡単に書く"
publish_date: "2015-10-19T07:34:38Z"
created: "2015-10-19T07:34:38Z"
updated: "2026-05-11T13:11:28.275Z"
categories: ["Python"]
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20230812/3fa70f28af184a26abb0fd4f584ab876.png.webp?width=768"
has_video: false
has_music: false
video_urls: []
music_urls: []
lang: "ja"
---

# プロセスプールを使って並列処理を簡単に書く

<div class="document">


<p>今までは、threading.Thread を使ってオレオレスレッドプールなんかを書いてたりしましたが、Pythonに用意されてないはずがないと思って探してみたら multiprosessing.pool.Pool がそれでした。超簡単にプロセスプールが作れる。今までの俺は何だったんだ。</p>
<p>追記: uwsgi でプロセスプールでの並列処理を動かしたら遅かった。原因は調べていない。threading.Thread での処理に切り替えたら快適になった。</p>
<pre class="literal-block">from multiprocessing.pool import Pool


def test_procedure():

    test_objects = HogeModel.getxxxxx

    with Pool(20) as p:
        for result in p.map(validate_hoge, test_objects):
            if result:
                print(result)
    print('ok')

def validate_hoge(test_object):
    遅い処理...
    return 処理結果
</pre>
<p>こんな感じでしょう。</p>
<p>ポイントとして、p.map に渡す第一引数は、クラスのメソッドとかではなくファイルの1階層に置いたファンクションにしとくのが無難。あとプロセス間でメモリを共有する場合はもう一工夫する。</p>
<p>今回は、ネットワークバウンドの処理を想定しているので、正直 mutiprocessing でも threding で並列にしてもそんなに差は無いと思います。正直どっちでもいい。が、CPUと効率的に使うとしたら GIL しない multiprocessing の方が良いでしょうね。</p>
<p>また、Pool の第一引数が プロセス数ですが、これも ネットワークバウンドの処理になる想定なので大きめにしています。CPUバウンドの処理の場合、引数なしで Pool を作ると搭載CPU数に応じて自動的に判断してくれるのでよさげです。</p>
<p>multiprocessing には、今回の Pool のような便利クラスが用意されているので、基本的にバッチなどでの並列処理を書くなら multiprocessing を使えば良いでしょう。</p>
<p>呼び出しコストはわかりません。大きな共有メモリが必要で、かつCPUをあまり使わない処理なら threading でしょうかね。</p>
</div>
