#python #multiprocessing
#python #многопроцессорная обработка
Вопрос:
В приведенном ниже коде я ожидал, что результат будет равен 2, поскольку я изменяю значение config перед назначением функции пулу для многопроцессорной обработки, но вместо этого я получаю 5. Я уверен, что для этого есть веская причина, но не уверен, как это объяснить.
from multiprocessing import Pool
config = 5
class Test:
def __init__(self):
print("This is init")
@classmethod
def testPrint(cls, data):
print(config)
print("This is testPrint")
return config
if __name__ == "__main__" :
pool = Pool()
config = 2
output = pool.map(Test.testPrint, range(10))
print(output)
Вывод
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
5
This is testPrint
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
Комментарии:
1. Я не знаю точно, что здесь происходит, но мы в некоторой степени используем многопроцессорную обработку, и мы научились избегать глобальных переменных. В какой-то момент создается копия среды с помощью травления, потому что у вас нет среды с общей памятью. Точно, что происходит с этим конкретным значением, я не могу сказать. Что я добавлю, так это предложить то, что мы узнали … передавайте все ваши общие значения очень явно, как в подпроцессах, так и особенно из них.
2. Похоже, что ответ @tdelaney идет по тому же пути, но с более подробной информацией. Все хорошо.
3. @Steve я ожидал, что запись общих значений в подпроцессах будет испорчена, но не чтение. Сегодня узнал кое-что новое.
Ответ №1:
Новые процессы создаются при создании пула. После этого изменения, внесенные в родительское пространство памяти, за исключением материалов, которые передаются в функции пула, например .map
, не видны подпроцессу. Системы разветвления, такие как Linux, создают представления копирования при записи в родительское пространство памяти, и эта запись приводит к созданию уникального блока памяти для родительского, не видимого подпроцессом. Порождающие системы повторно импортируют модули (устанавливая глобальные переменные), а затем пытаются определить / отменить состояние для подпроцессов. В обоих случаях это выполняется до Pool
того, как инициализация класса вернется в вашу программу.
Комментарии:
1. Спасибо за объяснение, я проверил, изменив значение config перед созданием пула. Он выводит желаемый результат.