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

Posted by: ytyng 6 years, 8 months 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 でしょうかね。

Currently unrated

Comments

Archive

2022
2021
2020
2019
2018
2017
2016
2015
2014
2013
2012
2011