[python] multiprocessingの基本的な使い方

pythonで処理を早く終わらせたい場面などがあると思います. 基本的にpythonのプログラムを実行すると1つのプロセスが立ち上がって処理をします. この処理を高速化するために複数のプロセスを立ち上げて並列処理することで実行時間を削減することができます. 少し難しいように感じますがpythonでは標準ライブラリにmultiprocessingというライブラリがあり, これを使うことで簡単に並列処理することができます. 今回はこのライブラリの簡単な使い方を紹介していきます.

pythonにおけるmultiprocessingの立ち位置

pythonでは処理を高速化する方法が大きく分けて2つあります. 複数のプロセスを立ち上げて並列処理するmultiprocessingを使用する方法と1つのプロセスを立ち上げて複数のスレッドで並列処理するthreadingがあります. threadingは実装するのが難しい上にそれぞれのクラスを正しく使用していないと多少の高速化をしかできないなど扱いづらい印象があります. その上プログラムがスレッドセーフでないと予期せぬ動作をしてしまいます. 一方, multiprocessingは実装が簡単であり高速化も容易にできます. また, スレッドを使用する代わりにサブプロセス(子プロセス)を使用することで,GILの問題を効率的に回避できるようになっているみたいです. このような理由から, 個人的にpythonで高速化するならmultiprocessingをおすすめします.

multiprocessingの使い方

pythonの標準ライブラリであるmultiprocessingを使い並列処理をする方法を説明していきます。multiprocessingでは並列処理したい処理を関数化し、その定義した関数をPoolクラスを用いて並列処理します。

最初にPoolクラスを生成しますが, その際に使用するコア数を指定します. 今回はマシンの最大使用可能コア数を指定しました. 並列処理したい内容を定義したfunction関数をPoolクラスのmapメソッドの引数で渡すことで実行することができます. mapメソッドの第二引数が並列処理する関数の引数となります. function関数内でsleep関数を使用していますが今回は処理が簡単だったので表示順が前後してしまうのでsleepさせました. 終了したらPoolクラスのcloseメソッドでプロセスを閉じます。closeを忘れると並列処理していたメモリが解放されずに残り続けるので気をつけてください.

子プロセス数は4つで, 親プロセスIDの2618に対して子プロセスIDは2621~2624の4つで実行されていることが分かります.

まとめ

今回は基本的なmultiprocessingの使い方を紹介しました. 実際に使うときは並列処理した結果を1つとして扱いたい場合がほとんどだと思います(並列処理した結果を配列に格納するなど). この場合は複数プロセスの間でメモリを共有することで, それぞれのプロセスの結果を共有することができます. 次回は複数プロセスの間でメモリを共有する方法を紹介します.