4

この質問は非常に一般的であり、十分に明確ではない可能性があるため、事前に謝罪する必要があります. 問題は、それ自体がいくつかのサブタスクにプロセスのプールを使用し、大量の I/O 操作を行う Python 関数をどのように並行して実行するかということです。それは有効なタスクですか?

もう少し情報を提供しようと思います。test_reduce()たとえば、並列に実行する必要があるプロシージャがあります。私はそれを行うためにいくつかの方法を試しましたが (以下を参照)、それらすべてが失敗する理由を理解するための知識が不足しているようです。

このtest_reduce()手順は多くのことを行います。それらのいくつかは、他のものよりも質問に関連しています(以下にリストします):

  • multiprocessingモジュール(sic!)、つまりpool.Poolインスタンスを使用します。
  • MongoDB 接続を使用し、
  • libs に大きく依存してnumpyおり、scikit-learn
  • コールバックとラムダを使用し、
  • ライブラリを使用して、dillいくつかのものをピクルスにします。

multiprocessing.dummy.Pool最初に(スレッドプールのようです)を使用しようとしました。このプールの具体的な内容と、なぜ「ダミー」なのかはわかりません。すべてが機能し、結果が得られました。問題はCPU負荷です。並列化されたセクションでtest_reduce()は、すべてのコアで 100% でした。同期セクションの場合、ほとんどの場合、約 40 ~ 50% でした。このタイプの「並列」実行の全体的な速度が向上したとは言えません。

次に、この手順のmultiprocessing.pool.Poolインスタンスを自分のデータに使用しようとしました。map以下で失敗しました。

File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
    raise self._value
cPickle.PicklingError: Can't pickle <type 'thread.lock'>: attribute lookup thread.lock failed

cPickle私はそれが原因であると推測しpathos、はるかに高度な pickler を使用するライブラリを見つけましたdill。ただし、失敗することもあります。

File "/local/lib/python2.7/site-packages/dill/dill.py", line 199, in load
    obj = pik.load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1083, in load_newobj
    obj = cls.__new__(cls, *args)
TypeError: object.__new__(generator) is not safe, use generator.__new__()

さて、このエラーは私がまったく理解していないものです。プールで機能する場合、プロシージャからの出力がないstdoutため、何が起こっているのかを推測するのは困難です。私が知っている唯一のことはtest_reduce()、マルチプロセッシングが使用されていない場合に正常に実行されることです。

では、これほど重くて複雑なものをどのように並行して実行するのでしょうか?

4

1 に答える 1

1

だから、@MikeMcKernsの答えのおかげで、libで仕事を成し遂げる方法を見つけましたpathospymongo私はすべてのカーソルを取り除く必要がありましたdill. そうすることで問題が解決し、コードを並行して実行することができました。

于 2015-07-08T13:09:49.630 に答える