El multiprocesamiento de Python apply_async nunca devuelve el resultado en Windows 7

Estoy tratando de seguir un ejemplo de multiprocesamiento muy simple:

import multiprocessing as mp def cube(x): return x**3 pool = mp.Pool(processes=2) results = [pool.apply_async(cube, args=x) for x in range(1,7)] 

Sin embargo, en mi máquina Windows, no puedo obtener el resultado (en ubuntu 12.04LTS funciona perfectamente).

Si inspecciono los results , veo lo siguiente:

 [, , , , , ] 

Si ejecuto results[0].ready() siempre obtengo False .

Si ejecuto results[0].get() el intérprete de Python se congela, esperando a obtener el resultado que nunca llega.

El ejemplo es tan simple como se ve, así que creo que este es un error de bajo nivel relacionado con el sistema operativo (estoy en Windows 7). Pero tal vez alguien más tiene una mejor idea?

Hay un par de errores aquí. Primero, debe declarar el grupo dentro de un if __name__ == "__main__": guard cuando se ejecuta en Windows . Segundo, tienes que pasar una secuencia al argumento de la palabra clave args , incluso si solo estás pasando un argumento. Así que juntando eso:

 import multiprocessing as mp def cube(x): return x**3 if __name__ == "__main__": pool = mp.Pool(processes=2) results = [pool.apply_async(cube, args=(x,)) for x in range(1,7)] print([result.get() for result in results]) 

Salida:

 [1, 8, 27, 64, 125, 216] 

Editar:

Oh, como lo menciona moarningsun, el multiprocessing no funciona bien en el intérprete interactivo:

Nota

La funcionalidad dentro de este paquete requiere que los __main__ puedan __main__ módulo __main__ . Esto está cubierto en las pautas de progtwigción, sin embargo, vale la pena señalarlo aquí. Esto significa que algunos ejemplos, como el multiprocessing.Pool ejemplos de las multiprocessing.Pool no funcionarán en el intérprete interactivo.

Por lo tanto, deberá ejecutar el código como una secuencia de comandos para probarlo correctamente.

Estaba ejecutando python 3 y el IDE era spyder en anaconda (windows), por lo que este truco no me funciona. Probé mucho pero no pude hacer ninguna diferencia. Tengo el motivo de mi problema y es el mismo que figura en su nota dano. Pero después de un largo día de búsqueda obtuve una solución y me ayudó a ejecutar el mismo código que mi máquina Windows. Este sitio web me ayudó a obtener la solución:

http://python.6.x6.nabble.com/Multiprocessing-Pool-woes-td5047050.html

Desde que estaba usando el python 3, cambié el progtwig de la siguiente manera:

 from types import FunctionType import marshal def _applicable(*args, **kwargs): name = kwargs['__pw_name'] code = marshal.loads(kwargs['__pw_code']) gbls = globals() #gbls = marshal.loads(kwargs['__pw_gbls']) defs = marshal.loads(kwargs['__pw_defs']) clsr = marshal.loads(kwargs['__pw_clsr']) fdct = marshal.loads(kwargs['__pw_fdct']) func = FunctionType(code, gbls, name, defs, clsr) func.fdct = fdct del kwargs['__pw_name'] del kwargs['__pw_code'] del kwargs['__pw_defs'] del kwargs['__pw_clsr'] del kwargs['__pw_fdct'] return func(*args, **kwargs) def make_applicable(f, *args, **kwargs): if not isinstance(f, FunctionType): raise ValueError('argument must be a function') kwargs['__pw_name'] = f.__name__ # edited kwargs['__pw_code'] = marshal.dumps(f.__code__) # edited kwargs['__pw_defs'] = marshal.dumps(f.__defaults__) # edited kwargs['__pw_clsr'] = marshal.dumps(f.__closure__) # edited kwargs['__pw_fdct'] = marshal.dumps(f.__dict__) # edited return _applicable, args, kwargs def _mappable(x): x,name,code,defs,clsr,fdct = x code = marshal.loads(code) gbls = globals() #gbls = marshal.loads(gbls) defs = marshal.loads(defs) clsr = marshal.loads(clsr) fdct = marshal.loads(fdct) func = FunctionType(code, gbls, name, defs, clsr) func.fdct = fdct return func(x) def make_mappable(f, iterable): if not isinstance(f, FunctionType): raise ValueError('argument must be a function') name = f.__name__ # edited code = marshal.dumps(f.__code__) # edited defs = marshal.dumps(f.__defaults__) # edited clsr = marshal.dumps(f.__closure__) # edited fdct = marshal.dumps(f.__dict__) # edited return _mappable, ((i,name,code,defs,clsr,fdct) for i in iterable) 

Después de esta función, el código de problema anterior también se cambia un poco así:

 from multiprocessing import Pool from poolable import make_applicable, make_mappable def cube(x): return x**3 if __name__ == "__main__": pool = Pool(processes=2) results = [pool.apply_async(*make_applicable(cube,x)) for x in range(1,7)] print([result.get(timeout=10) for result in results]) 

Y tengo la salida como:

 [1, 8, 27, 64, 125, 216] 

Estoy pensando que esta publicación puede ser útil para algunos de los usuarios de Windows.