Как вы можете прочитать от the answer, указанном Джоном в комментариях, multiprocessing.Pool
, как правило, не должно нормально работать в интерактивном интерпретаторе. Чтобы понять, почему это так, рассмотрим, как Pool
делает свою работу:
- It рабочих вилки питона, передавая им имя текущего файла Python.
- Рабочие тогда по существу делают
import <this file>
и прислушиваются к сообщениям от мастера.
- Мастер отправляет имена функций вместе с аргументами функции рабочим через травление. Обратите внимание, что сами функции не могут быть отправлены, потому что протокол рассола не позволяет этого.
При попытке выполнить эту процедуру из интерактивного приглашения нет разумного «текущего файла Python» для передачи детям для импорта. Кроме того, функции, которые вы определили в своем интерактивном приглашении, не являются частью какого-либо модуля (они динамически определены) и, следовательно, не могут быть импортированы дочерними элементами из этого несуществующего модуля. Таким образом, ваша самая легкая ставка заключается в том, чтобы просто не использовать multiprocessing
в IPython. IPython parallel намного лучше в любом случае :)
Для полноты ради я также проверил, что именно происходит в моем конкретном случае IPython 4 работает под Python 2.7 на Windows 8 (где я могу наблюдать за переводчика застрять в Что ж). Интересно, что причина, по которой IPython застревает в первую очередь, не является одной из упомянутых выше.
Оказывается, что многопроцессорность проверяет, определено ли значение __main__.__file__
, а если нет, отправляет sys.argv[0]
в качестве «текущего имени файла» для детей. В случае (моя версия) IPython sys.argv[0]
равен C:\Dev\Anaconda\lib\site-packages\ipykernel\__main__.py
.
К сожалению, рабочие процессы перед запуском происходят, чтобы проверить, находится ли файл, который они будут импортировать, уже в их sys.modules
. Линия 488 multiprocessing/forking.py
говорит:
assert main_name not in sys.modules, main_name
Когда main_name
является __main__
(как в случае с работниками IPython в) это утверждение не удается, и рабочие не запуститься. Тем не менее, один и тот же код является «умным», чтобы проверить, является ли переданное имя ipython
, и в этом случае он не делает таких проверок и ничего не импортирует.
Следовательно, проблема рабочих, которые не могут начать, может быть решена с помощью уродливого взлома определения __main__.__file__
равным ipython
. Следующий код работает отлично от клетки IPython:
import sys
sys.modules['__main__'].__file__ = 'ipython'
from multiprocessing import Pool
pool = Pool(processes=4)
inputs = [0, 1, 2, 3, 4]
outputs = pool.map(abs, inputs)
Обратите внимание, что этот пример просит рабочий вычислить abs
, встроенную функцию.Он потерпит неудачу (изящно, с исключением), если вы попросите рабочих вычислить функцию, определенную вами в записной книжке.
Оказалось, что в принципе вы можете продолжить хакерство и передать свои функции рабочим, используя ручную травление их кода. Вы можете найти довольно классный пример такого взлома here.
Этот код работает в обычном (не-Notebook) Python. Можете ли вы подтвердить, что он работает в вашей системе за пределами ноутбука? Можете ли вы также заменить часть пула на регулярную 'map()', чтобы подтвердить, что работает внутри ноутбука? См. Также http://stackoverflow.com/a/23641560/4323 –
работает для меня. Вы можете добавить более подробную информацию, например. версия 'ipython', ОС и т. д. – cel