Многопроцессорная обработка python apply_async никогда не возвращает результат в Windows 7

Я пытаюсь выполнить очень простой пример многопроцессорности:

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)] 

Однако на моей машине с Windows я не могу получить результат (на ubuntu 12.04LTS он работает отлично).

Если я проверю results , я вижу следующее:

 [<multiprocessing.pool.ApplyResult object at 0x01FF0910>, <multiprocessing.pool.ApplyResult object at 0x01FF0950>, <multiprocessing.pool.ApplyResult object at 0x01FF0990>, <multiprocessing.pool.ApplyResult object at 0x01FF09D0>, <multiprocessing.pool.ApplyResult object at 0x01FF0A10>, <multiprocessing.pool.ApplyResult object at 0x01FF0A50>] 

Если я запускаю results[0].ready() я всегда получаю False .

Если я запустил results[0].get() интерпретатор python зависает, ожидая получения результата, которого никогда не будет.

Пример такой же простой, как и он, поэтому я думаю, что это ошибка низкого уровня, связанная с ОС (я нахожусь в Windows 7). Но, возможно, у кого-то есть лучшая идея?

Здесь есть несколько ошибок. Во-первых, вы должны объявить Pool внутри if __name__ == "__main__": защита при работе в Windows . Во-вторых, вам нужно передать args ключевого слова args , даже если вы передаете только один аргумент. Итак, поставим это вместе:

 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]) 

Вывод:

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

Редактировать:

О, как упоминает moarningsun, multiprocessing не работает в интерактивном интерпретаторе:

Заметка

Функциональность в этом пакете требует, чтобы модуль __main__ был импортирован дочерними элементами. Это описано в Руководстве по программированию, однако это стоит отметить здесь. Это означает, что некоторые примеры, такие как примеры multiprocessing.Pool , не будут работать в интерактивном интерпретаторе.

Поэтому вам действительно нужно выполнить код как скрипт, чтобы проверить его правильно.

Я запускал python 3, а IDE был spyder в anaconda (windows), и поэтому этот трюк не работает для меня. Я много пробовал, но не имел никакого значения. Я получил причину своей проблемы и тот же, что и Дано в записке. Но после долгого дня поиска у меня появилось какое-то решение, и это помогло мне запустить тот же код на моем компьютере с Windows. Этот сайт помог мне найти решение:

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

Поскольку я использовал python 3, я немного изменил программу:

 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) 

После этой функции вышеупомянутый код проблемы также немного изменился:

 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]) 

И я получил результат как:

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

Я думаю, что этот пост может быть полезен для некоторых пользователей Windows.