Kiedy biegnę coś takiego:
from multiprocessing import Pool
p = Pool(5)
def f(x):
return x*x
p.map(f, [1,2,3])
to działa dobrze. Jednak umieszczając to jako funkcję klasy:
class calculate(object):
def run(self):
def f(x):
return x*x
p = Pool()
return p.map(f, [1,2,3])
cl = calculate()
print cl.run()
Daje mi następujący błąd:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/sw/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/sw/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "/sw/lib/python2.6/multiprocessing/pool.py", line 225, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Widziałem post Alexa Martelliego dotyczący tego samego problemu, ale nie był wystarczająco jasny.
IPython.Parallel
środku, ale tam można było obejść ten problem, popychając obiekty do węzłów. Obejście tego problemu z przetwarzaniem wieloprocesowym wydaje się dość denerwujące.
calculate
jest picklable, a więc wydaje się, że może to zostać rozwiązane przez: 1) tworzenia obiektów funkcji z konstruktora kopie nad calculate
przykład, a następnie 2) przechodzącego wystąpienie tego obiektu funkcyjnej, Pool
jest map
sposobem. Nie?
multiprocessing
modułu wynikają z jego celu, jakim jest implementacja międzyplatformowa, oraz braku fork(2)
podobnego wywołania systemowego w systemie Windows. Jeśli nie zależy Ci na obsłudze Win32, może istnieć prostsze obejście oparte na procesach. Lub jeśli jesteś przygotowany do korzystania wątki zamiast procesów, można zastąpić from multiprocessing import Pool
z from multiprocessing.pool import ThreadPool as Pool
.