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

Python
2015-10-19 07:34 (10 years ago)
プロセスプールを使って並列処理を簡単に書く

今までは、threading.Thread を使ってオレオレスレッドプールなんかを書いてたりしましたが、Pythonに用意されてないはずがないと思って探してみたら multiprosessing.pool.Pool がそれでした。超簡単にプロセスプールが作れる。今までの俺は何だったんだ。

追記: uwsgi でプロセスプールでの並列処理を動かしたら遅かった。原因は調べていない。threading.Thread での処理に切り替えたら快適になった。

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 処理結果

こんな感じでしょう。

ポイントとして、p.map に渡す第一引数は、クラスのメソッドとかではなくファイルの1階層に置いたファンクションにしとくのが無難。あとプロセス間でメモリを共有する場合はもう一工夫する。

今回は、ネットワークバウンドの処理を想定しているので、正直 mutiprocessing でも threding で並列にしてもそんなに差は無いと思います。正直どっちでもいい。が、CPUと効率的に使うとしたら GIL しない multiprocessing の方が良いでしょうね。

また、Pool の第一引数が プロセス数ですが、これも ネットワークバウンドの処理になる想定なので大きめにしています。CPUバウンドの処理の場合、引数なしで Pool を作ると搭載CPU数に応じて自動的に判断してくれるのでよさげです。

multiprocessing には、今回の Pool のような便利クラスが用意されているので、基本的にバッチなどでの並列処理を書くなら multiprocessing を使えば良いでしょう。

呼び出しコストはわかりません。大きな共有メモリが必要で、かつCPUをあまり使わない処理なら threading でしょうかね。

まだ評価がありません
著者は、アプリケーション開発会社 Cyberneura を運営しています。
開発相談をお待ちしています。

アーカイブ