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

(コメント)

今までは、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

    https://t.co/4BcaKOjNBq ヒカキンさんのマンガ買ったもらった動画を公開後、サイト負荷限界になったけど急いでスケールアップしましたよ。マンガ買ってってー
    1 週間, 5 日 前

  • ytyng

    ytyng @ytyng

    ラズパイ3届いたので倉庫用のスマート時計作る https://t.co/9TfZHOkeTu
    2 週間, 5 日 前

  • ytyng

    ytyng @ytyng

    bootstrap cdn が少しダウンしてた。https://t.co/olTmNrJy33 / https://t.co/M4IqniWeWj どちらも。
    1 ヶ月, 1 週間 前