#python #windows #multiprocessing
#python #Windows #многопроцессорная обработка
Вопрос:
Я узнаю о пуле, менеджере и т. Д. Из многопроцессорной обработки. Я хочу использовать пространство имен в диспетчере в своей функции. Я взял из Интернета некоторый код, в котором освещается проблема диспетчера многопроцессорной обработки в Windows. Вот оно:
"""How to share data in multiprocessing with Manager.Namespace()"""
from multiprocessing import Pool, Manager
import numpy as np
# Create manager object in module-level namespace
mgr = Manager()
# Then create a container of things that you want to share to
# processes as Manager.Namespace() object.
config = mgr.Namespace()
# The Namespace object can take various data type
config.a = 1
config.b = '2'
config.c = [1, 2, 3, 4]
def func(i):
"""This is a function that we want our processes to call."""
# You can modify the Namespace object from anywhere.
config.z = i
print('config is', config)
# And they will still be shared (i.e. same id).
print('id(config) = {:d}'.format(id(config)))
# This main func
def main():
"""The main function contain multiprocess.Pool codes."""
# You can add to the Namespace object too.
config.d = 10
config.a = 5.25e6
pool = Pool(1)
pool.map(func, (range(20, 25)))
pool.close()
pool.join()
if __name__ == "__main__":
# Let's print the config
print(config)
# Now executing main()
main()
# Again, you can add or modify the Namesapce object from anywhere.
config.e = np.round(np.random.rand(2,2), 2)
config.f = range(-3, 3)
print(config)
Ошибка заключается в следующем:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
Проблема, я думаю, в том, что менеджер загружается с глобальной переменной. Вы не можете сделать это с Windows. Как вы можете видеть, я защищаю main, но этого недостаточно. Что нужно сделать, так это каким-то образом передать менеджер функции (возможно, в переменные карты), но я не знаю, как это сделать.
Ответ №1:
Да, похоже, что создание менеджера как глобального вызывает проблемы в Windows. Переместите его в модуль main и передайте пространство имен в качестве параметра. Pool.map() позволяет передавать только один аргумент рабочему, поэтому поместите несколько аргументов, включая пространство имен, в список. Передайте список списков аргументов в Pool.map().
Возможно, я ошибаюсь, но я не думаю, что вам следует ожидать / требовать, чтобы идентификаторы объектов не менялись.
from multiprocessing import Pool, Manager
import numpy as np
def func(a):
"""This is a function that we want our processes to call."""
(config, i) = a
# You can modify the Namespace object from anywhere.
config.z = i
print('config is', config)
# And they will still be shared (i.e. same id).
print('id(config) = {:d}'.format(id(config)))
# This main func
def main(config):
"""The main function contain multiprocess.Pool codes."""
# You can add to the Namespace object too.
config.d = 10
config.a = 5.25e6
pool = Pool(1)
pool.map(func, list([config, i] for i in range(20,25)))
pool.close()
pool.join()
if __name__ == "__main__":
# Create manager object in module-level namespace
mgr = Manager()
# Then create a container of things that you want to share to
# processes as Manager.Namespace() object.
config = mgr.Namespace()
# The Namespace object can take various data type
config.a = 1
config.b = '2'
config.c = [1, 2, 3, 4]
# Let's print the config
print(config)
# Now executing main()
main(config)
# Again, you can add or modify the Namesapce object from anywhere.
config.e = np.round(np.random.rand(2,2), 2)
config.f = range(-3, 3)
print(config)
Комментарии:
1. Привет, Даррен. Спасибо за ответ. Я пытался получить помощь от своих друзей по этому вопросу, но их это не беспокоило. Я сообщу им, что мне пришлось обратиться за помощью к незнакомцу. Будьте в безопасности.