申し訳ありませんが、より簡単な例でエラーを再現することはできません。また、コードは投稿するには複雑すぎます。通常の Python ではなく IPython シェルでプログラムを実行すると、うまくいきます。
この問題に関する以前のメモをいくつか調べました。それらはすべて、クラス関数内で定義された関数を呼び出すためにプールを使用することによって発生していました。しかし、これは私の場合は当てはまりません。
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 313, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
ご協力いただければ幸いです。
更新: pickle する関数は、モジュールのトップ レベルで定義されています。ただし、ネストされた関数を含む関数を呼び出します。つまり、 はネストされた関数を持つ をf()
呼び出し、 を呼び出しています。、g()
はすべてトップ レベルで定義されています。このパターンを使用してより単純な例を試してみましたが、うまくいきました。h()
i()
pool.apply_async(f)
f()
g()
h()
ベストアンサー1
がここにあります漬けられるもののリスト特に、関数はモジュールのトップレベルで定義されている場合にのみ pickle 化可能です。
このコード:
import multiprocessing as mp
class Foo():
@staticmethod
def work(self):
pass
if __name__ == '__main__':
pool = mp.Pool()
foo = Foo()
pool.apply_async(foo.work)
pool.close()
pool.join()
あなたが投稿したものとほぼ同じエラーが発生します:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 315, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
問題は、pool
メソッドがすべて を使ってmp.SimpleQueue
タスクをワーカー プロセスに渡すことです。 を通過するものはすべてmp.SimpleQueue
pickable である必要があり、foo.work
モジュールの最上位レベルで定義されていないため picklable ではありません。
これは、トップレベルで次の関数を定義することで修正できますfoo.work()
。
def work(foo):
foo.work()
pool.apply_async(work,args=(foo,))
はトップレベルで定義されており、foo
pickle 化可能であるため、選択可能であることに注意してください。Foo
foo.__dict__