Использование Python multiprocessing.pool.map для манипулирования одним и тем же целым числом

проблема

Я использую многопроцессорный модуль Python для асинхронного выполнения функций. То, что я хочу сделать, это иметь возможность отслеживать общий прогресс моего сценария, когда каждый процесс вызывает и выполняет def add_print, Например, я хотел бы, чтобы код ниже добавил 1 к total и распечатать значение (1 2 3 ... 18 19 20) каждый раз, когда процесс запускает эту функцию. Моей первой попыткой было использование глобальной переменной, но это не сработало. Поскольку функция вызывается асинхронно, каждый процесс читает total как 0, чтобы начать, и добавляет 1 независимо от других процессов. Таким образом, выход составляет 20 1вместо увеличения значений.

Как я могу получить ссылку на один и тот же блок памяти из моей сопоставленной функции синхронно, даже если функция выполняется асинхронно? У меня была идея как-то кешировать total в памяти, а затем ссылаться на этот точный блок памяти, когда я добавляю к total, Это возможный и принципиально правильный подход в питоне?

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация или я что-то не объяснил достаточно хорошо.

Спасибо!


Код

#!/usr/bin/python

## Import builtins
from multiprocessing import Pool 

total = 0

def add_print(num):
    global total
    total += 1
    print total


if __name__ == "__main__":
    nums = range(20)

    pool = Pool(processes=20)
    pool.map(add_print, nums)

1 ответ

Решение

Вы можете использовать общийValue:

import multiprocessing as mp

def add_print(num):
    total.value += 1
    print(total.value)

def setup(t):
    global total
    total = t

if __name__ == "__main__":
    total = mp.Value('i', 0)       
    nums = range(20)
    pool = mp.Pool(initializer=setup, initargs=[total])
    pool.map(add_print, nums)

Вызов инициализатора пула setup один раз для каждого рабочего подпроцесса. setupмарки total глобальная переменная в рабочем процессе, так total можно получить доступ внутри add_print когда рабочий звонит add_print,

Обратите внимание, что количество процессов не должно превышать количество процессоров на вашей машине. Если вы это сделаете, избыточные подпроцессы будут ждать, пока процессоры станут доступными. Так что не используйте processes=20 если у вас нет 20 или более процессоров. Если вы не поставите processes аргумент, multiprocessing определит количество доступных процессоров и создаст пул с таким количеством рабочих для вас. Количество заданий (например, длина nums) обычно значительно превышает количество процессоров. Все в порядке; задачи ставятся в очередь и обрабатываются одним из рабочих, когда рабочий становится доступным.

Другие вопросы по тегам