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

(コメント)

今までは、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 でしょうかね。

現在未評価

コメント

最近のツイート

  • ytyng

    ytyng @ytyng

    俺もスタバアプリにログインできないよ
    3 ヶ月 前

  • 安藤拓郎 Takuro Ando

    安藤拓郎 Takuro Ando @takuroando

    ytyng

    これまでいろんなグッズを作ってきたけど、今回は「お米」と聞いて買うしかないなと。今夜の夕食はコシヒカリ!箸もセットだし^^ https://t.co/01ucQx9qtw #腰乃展 #マンガ展 https://t.co/4VL2vOe0Og
    3 ヶ月, 2 週間 前

  • ytyng

    ytyng @ytyng

    講談社さんとやった全部入り電子書籍セットがギネスブックに登録されたよー https://t.co/rbkd3IYub0
    3 ヶ月, 2 週間 前