multiprocessing.Manager().dict()使用坑点

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()字典时,如果是嵌套字典,当腰修改最内层的字典键值时,不能直接修改,需要用一个中间变量去转接一下

你可能感兴趣的:(python,开发语言)