Возможно ли, чтобы несколько процессов записывали в один и тот же словарь, используя Pool.map ()? - PullRequest
2 голосов
/ 06 марта 2019

Я использую python3.6 и пытаюсь выполнить что-то похожее на следующий код.Однако после выполнения переменная mydict остается {}

Я пробовал это с global mydict и без.Я думал, что по умолчанию глобальные диктовки, но ни один из них не работает.

mydict = {}
def TEST(hello, integer):
    global mydict
    mydict[integer] = hello
    print(integer)
with closing(Pool(processes=4)) as pool:
    pool.starmap(TEST, [['Hello World', i] for i in range(200)])

Возможно ли, чтобы несколько процессов записывали в один и тот же словарь в python?

1 Ответ

2 голосов
/ 06 марта 2019

Возможно ли, чтобы несколько процессов записывали в один и тот же словарь в python?

Нет, словари нельзя разделять между процессами, потому что каждый из них работает вотдельное пространство памяти с кодом Python, интерпретируемым различными копиями интерпретатора, хотя это может быть сделано через общую память для некоторых других типов данных.

Однако его можно смоделировать с помощью multiprocessing.Manager() для координации обновлений определенных типов общих объектов - и один из поддерживаемых типов - dict.

Это обсуждается в состоянии общего доступа между процессами в онлайн-документации.Использование Manager связано с большими накладными расходами, поскольку они выполняются как отдельный серверный процесс параллельно с любыми другими процессами, которые создает ваш код.

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

from contextlib import closing
from multiprocessing import Pool, Manager

def TEST(mydict, hello, integer):
    mydict[integer] = hello
    print(integer)

if __name__ == '__main__':

    with Manager() as manager:
        my_dict = manager.dict()

        with closing(Pool(processes=4)) as pool:
            pool.starmap(TEST, ((my_dict, 'Hello World', i) for i in range(200)))
...