Почему python использует вызов функции CallByValue, когда dict (изменяемый dtype) является аргументом функции, которая реализуется через пул многопроцессорной обработки? - PullRequest
0 голосов
/ 03 мая 2020

Примечание: это надуманный пример более серьезной проблемы

from multiprocessing import Pool

dict1 = {'key1':1}

def alterDict(dict_num):
    for key in dict_num:
        dict_num[key] = 20000

alterDict(dict1)
print(dict1) # output is {'key1': 20000}



dict1 = {'key1':1}


with Pool(2) as p:
    p.map(alterDict,[dict1])

print(dict1) # output is {'key1': 1}

Почему выходы разные? Есть ли способ обойти Pool от использования стиля вызова по значению при вызове функции? Я хочу, чтобы пул использовал вызов по ссылочному стилю вызова функции

1 Ответ

0 голосов
/ 03 мая 2020

когда вы используете multiprocessing и хотите изменить объект, например dict, list et c .. (общие данные), вам необходимо использовать Состояние обмена между процессами .

import multiprocessing as mp

def alterDict(dict_num): 
    for key, _ in dict_num.items(): 
        dict_num[key] = 20000 

with mp.Manager() as manager: 
    d = manager.dict() 
    d['key'] = 1 
    with manager.Pool() as pool: 
        pool.map(alterDict, [d]) 
    print(dict(d)) 

# {'key': 20000} # output

Кстати, вы должны использовать dict_num.items() с items, иначе вы получите ошибку:

/usr/local/lib/python3.8/multiprocessing/managers.py in _callmethod(self, methodname, args, kwds)
    848             dispatch(conn, None, 'decref', (token.id,))
    849             return proxy
--> 850         raise convert_to_error(kind, result)
    851 
    852     def _getvalue(self):

AttributeError: 'NoneType' object has no attribute '_registry'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...