Pythonのmultiprocessing.PoolでExceptionを受け取る
Pythonで並列にいろいろ処理させたいなと思い、multiprocessing.Poolをつかってプログラムを作っていたらぶち当たった問題。
下記のコードを動かしていた、実はバグあり。
出力は
start main end main
??おかしい。本当ならworkerのprint関数が実行される、はず。
実は
res = pool.apply_async(worker, (i))
じゃなくて
res = pool.apply_async(worker, (i,))
じゃないといけない。引数をタプルとして認識してくれないのが原因だ。
修正してみる。
出力は
start main worker i: 0 worker i: 1 worker i: 2 worker i: 3 worker i: 4 worker i: 5 worker i: 6 worker i: 7 end worker end worker end worker end worker end worker end worker end worker end worker end main
おー、治った。 しかしながら、エラーがわからん!!
困った、Exception出して欲しいよ(´・ω・`)
ちょっとWorkerでException投げてテストしてみる。 i == 6の時に例外を投げる。
出力
start main worker i: 0 worker i: 1 worker i: 2 worker i: 3 worker i: 4 worker i: 5 worker i: 6 worker i: 7 end worker: 1 end worker: 2 end worker: 3 end worker: 0 end worker: 4 end worker: 5 end worker: 7 end main
うん、正常に動いて、ないね。6番が抜けてるけど、Exceptionはスルー。 困った。 教えて、すたっくおーばーふろー先生。
python - Exception thrown in multiprocessing Pool not detected - Stack Overflow
16.6. multiprocessing — Process-based “threading” interface — Python v2.7.6 documentation
なるほど、AsyncResult.get()という関数を使うと例外が投げられるのね
get()を呼んでみる。
start main worker i: 0 worker i: 1 worker i: 2 worker i: 3 worker i: 4 worker i: 5 worker i: 6 end worker: 1 end worker: 0 worker i: 7 end worker: 2 end worker: 5 end worker: 3 end worker: 4 end worker: 7 end main Traceback (most recent call last): File "pool_test_4.py", line 30, in <module> main() File "pool_test_4.py", line 26, in main res.get() File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 554, in get raise self._value Exception: help me! 6
おー、でたでた! res.get()、覚えておこう。 これで快適multiprocessing生活(・∀・)