当字典(可变数据类型)是通过多处理池实现的函数的参数时,为什么 python 使用 'CallByValue' 函数调用?
Why python uses 'CallByValue' function call when a dict (mutable dtype) is an argument to a function that is implemented via multiprocessing Pool?
注意:这是针对更大问题的人为示例
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
使用 'call by value' 风格的函数调用?
我想让池使用函数调用的引用调用方式
当您使用 multiprocessing
并且您想要更改 dict
、list
等对象时。(共享数据)您需要使用 Sharing state between process。
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'
注意:这是针对更大问题的人为示例
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
使用 'call by value' 风格的函数调用?
我想让池使用函数调用的引用调用方式
当您使用 multiprocessing
并且您想要更改 dict
、list
等对象时。(共享数据)您需要使用 Sharing state between process。
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'