Quando executo algo como:
from multiprocessing import Pool
p = Pool(5)
def f(x):
return x*x
p.map(f, [1,2,3])
Funciona bem. No entanto, colocando isso como uma função de uma 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()
Dá-me o seguinte erro:
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
Eu vi um post de Alex Martelli lidando com o mesmo tipo de problema, mas não era explícito o suficiente.
IPython.Parallel, mas era possível contornar o problema empurrando os objetos para os nós. Parece muito chato contornar esse problema com o multiprocessamento.
calculateé selecionável, então parece que isso pode ser resolvido por 1) criando um objeto de função com um construtor que copia sobre uma calculateinstância e 2) passando uma instância desse objeto de função para Poolo mapmétodo de. Não?
multiprocessingmódulo devem-se ao objetivo de ser uma implementação de plataforma cruzada e à falta de uma fork(2)chamada de sistema semelhante no Windows. Se você não se importa com o suporte ao Win32, pode haver uma solução alternativa baseada em processo mais simples. Ou, se você estiver preparado para usar threads em vez de processos, poderá substituí from multiprocessing import Pool-lo from multiprocessing.pool import ThreadPool as Pool.