Quand je lance quelque chose comme:
from multiprocessing import Pool
p = Pool(5)
def f(x):
return x*x
p.map(f, [1,2,3])
ça fonctionne bien. Cependant, en mettant cela en fonction d'une classe:
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()
Me donne l'erreur suivante:
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
J'ai vu un article d'Alex Martelli traitant du même genre de problème, mais ce n'était pas assez explicite.
IPython.Parallel
, mais là, vous pouvez contourner le problème en poussant les objets vers les nœuds. Il semble assez ennuyeux de contourner ce problème avec le multitraitement.
calculate
c'est picklable, il semble donc que cela puisse être résolu en 1) créant un objet fonction avec un constructeur qui copie sur une calculate
instance, puis 2) passant une instance de cet objet fonction à Pool
la map
méthode de. Non?
multiprocessing
module sont dues à son objectif d'être une implémentation multiplateforme et à l'absence d' fork(2)
appel système de type- like dans Windows. Si vous ne vous souciez pas de la prise en charge de Win32, il existe peut-être une solution de contournement plus simple basée sur les processus. Ou si vous êtes prêt à utiliser des threads au lieu de processus, vous pouvez les remplacer from multiprocessing import Pool
par from multiprocessing.pool import ThreadPool as Pool
.