Подтвердить что ты не робот

Параллельная карта python (multiprocessing.Pool.map) с глобальными данными

Я пытаюсь вызвать функцию для нескольких процессов. Очевидным решением является модуль python multiprocessing. Проблема в том, что функция имеет побочные эффекты. Он создает временный файл и регистрирует этот файл для удаления при выходе с помощью atexit.register и глобального списка. Следующее должно продемонстрировать проблему (в другом контексте).

import multiprocessing as multi

glob_data=[]
def func(a):
    glob_data.append(a)

map(func,range(10))
print glob_data  #[0,1,2,3,4 ... , 9]  Good.

p=multi.Pool(processes=8)
p.map(func,range(80))

print glob_data  #[0,1,2,3,4, ... , 9] Bad, glob_data wasn't updated.

Есть ли способ обновить глобальные данные?

Обратите внимание, что если вы попробуете приведенный выше script, вам, вероятно, не следует пытаться использовать его из интерактивного интерпретатора, поскольку multiprocessing требует, чтобы модуль __main__ был импортирован дочерними процессами.

UPDATE

Добавлено ключевое слово global в func не помогает - например:

def func(a):  #Still doesn't work.
    global glob_data
    glob_data.append(a)
4b9b3361

Ответ 1

Вам нужен список glob_data для поддержки общей памяти, Multiprocessing Manager дает вам именно это:

import multiprocessing as multi
from multiprocessing import Manager

manager = Manager()

glob_data = manager.list([])

def func(a):
    glob_data.append(a)

map(func,range(10))
print glob_data  # [0,1,2,3,4 ... , 9] Good.

p = multi.Pool(processes=8)
p.map(func,range(80))

print glob_data # Super Good.

Для некоторого фона:

https://docs.python.org/3/library/multiprocessing.html#managers

Ответ 2

Попросите func вернуть кортеж с результатами, которые вы хотите от обработки, и тем, что вы хотите добавить в glob_data. Затем, когда p.map завершен, вы можете извлечь результаты из первых элементов в возвращаемых кортежах, и вы можете построить glob_data из вторых элементов.