Python中写多进程的程序,可以使用multiprocessing.Manager模块可以实现进程间共享数据。
这里主要记录一下自己在使用multiprocessing.Manager().dict()时踩的坑
multiprocessing.Manager().dict()可以对简单字典进行传参并且可修改,但是对于嵌套字典,在主进程内修改最内层的字典值,修改无效。
实验结论:使用multiprocessing.Manager().dict()字典时,如果是嵌套字典,当腰修改最内层的字典键值时,不能直接修改,需要用一个中间变量去转接一下。
实验记录如下
multi_dict = multiprocessing.Manager().dict()
#嵌套字典
multi_dict = {"camer1": {'Intrude': 'ON'}}
#简单字典
multi_dict = {'Intrude': 'ON'}
直接修改multiprocessing 嵌套字典 测试代码
import multiprocessing
import time
def fun(sub_multi_dict):
while True:
print("子进程打印的", sub_multi_dict)
if sub_multi_dict["camer1"]['Intrude'] == "ON":
time.sleep(2)
elif sub_multi_dict["camer1"]['Intrude'] == "OFF":
break
if __name__=='__main__':
multi_dict = multiprocessing.Manager().dict()
# 嵌套字典
multi_dict["camer1"] = {'Intrude': 'ON'}
print("主进程内原始的multi_dict:",multi_dict)
Pools = multiprocessing.Pool(3)
Pools.apply_async(fun, (multi_dict,))
Pools.close()
# sleep 2s ,直接更新嵌套字典的最内层的value
time.sleep(4)
multi_dict["camer1"]['Intrude'] = 'OFF'
print("主进程内更新后的multi_dict:", multi_dict)
Pools.join()
#测试结果:可以看到,主进程并没有更新成功,所以子进程还是{'camer1': {'Intrude': 'ON'}}
主进程内原始的multi_dict: {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
主进程内更新后的multi_dict: {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
......
间接修改multiprocessing 嵌套字典 测试代码
import multiprocessing
import time
def fun(sub_multi_dict):
while True:
print("子进程打印的", sub_multi_dict)
if sub_multi_dict["camer1"]['Intrude'] == "ON":
time.sleep(2)
elif sub_multi_dict["camer1"]['Intrude'] == "OFF":
break
if __name__=='__main__':
multi_dict = multiprocessing.Manager().dict()
# 嵌套字典
multi_dict["camer1"] = {'Intrude': 'ON'}
print("主进程内原始的multi_dict:",multi_dict)
Pools = multiprocessing.Pool(3)
Pools.apply_async(fun, (multi_dict,))
Pools.close()
# sleep 2s
time.sleep(4)
#间接更新嵌套字典的最内层的value
dict = {'Intrude': 'OFF'}
multi_dict["camer1"]= dict
print("主进程内更新后的multi_dict:", multi_dict)
Pools.join()
#测试结果:可以看到,通过dict变量间接修改字典value,然后再将dict赋给multi_dict,即修改成功
主进程内原始的multi_dict: {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
子进程打印的 {'camer1': {'Intrude': 'ON'}}
主进程内更新后的multi_dict: {'camer1': {'Intrude': 'OFF'}}
子进程打印的 {'camer1': {'Intrude': 'OFF'}}
直接修改multiprocessing 简单字典 测试代码
import multiprocessing
import time
def fun(sub_multi_dict):
while True:
print("子进程打印的", sub_multi_dict)
if sub_multi_dict["camer1"] == "ON":
time.sleep(2)
elif sub_multi_dict["camer1"] == "OFF":
break
if __name__=='__main__':
multi_dict = multiprocessing.Manager().dict()
# 嵌套字典
multi_dict["camer1"] = 'ON'
print("主进程内原始的multi_dict:",multi_dict)
Pools = multiprocessing.Pool(3)
Pools.apply_async(fun, (multi_dict,))
Pools.close()
# sleep 2s ,直接更新嵌套字典的最内层的value
time.sleep(4)
multi_dict["camer1"] ='OFF'
print("主进程内更新后的multi_dict:", multi_dict)
Pools.join()
#测试结果: 主进程内,字典更新成功,随之子进程也更新成功
主进程内原始的multi_dict: {'camer1': 'ON'}
子进程打印的 {'camer1': 'ON'}
子进程打印的 {'camer1': 'ON'}
主进程内更新后的multi_dict: {'camer1': 'OFF'}
子进程打印的 {'camer1': 'OFF'}
直接修改非multiprocessing.Manager() 嵌套字典 测试代码
import time
if __name__=='__main__':
# multi_dict = multiprocessing.Manager().dict()
multi_dict ={}
# 嵌套字典
multi_dict["camer1"] = {'Intrude': 'ON'}
print("原始的multi_dict:",multi_dict)
# sleep 2s ,直接更新嵌套字典的最内层的value
time.sleep(4)
multi_dict["camer1"]['Intrude'] = 'OFF'
print("更新后的multi_dict:", multi_dict)
#测试结果:更新成功
原始的multi_dict: {'camer1': {'Intrude': 'ON'}}
更新后的multi_dict: {'camer1': {'Intrude': 'OFF'}}
直接修改非multiprocessing.Manager() 简单字典 测试代码
import time
if __name__=='__main__':
# multi_dict = multiprocessing.Manager().dict()
multi_dict ={}
# 嵌套字典
multi_dict["camer1"] ='ON'
print("原始的multi_dict:",multi_dict)
# sleep 2s ,直接更新嵌套字典的最内层的value
time.sleep(4)
multi_dict["camer1"] = 'OFF'
print("更新后的multi_dict:", multi_dict)
#测试结果:更新成功
原始的multi_dict: {'camer1': 'ON'}
更新后的multi_dict: {'camer1': 'OFF'}
结论:使用multiprocessing.Manager().dict()字典时,如果是嵌套字典,当腰修改最内层的字典键值时,不能直接修改,需要用一个中间变量去转接一下