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

本文介绍了在Python中使用multiprocessing.Manager().dict()时遇到的问题,特别是关于修改嵌套字典的键值。实验表明,直接修改嵌套字典的最内层键值可能无法在子进程中同步,而需要通过中间变量来实现正确的更新。对于简单字典,直接修改则可以成功。文章提供了直接和间接修改的示例代码及测试结果,强调了使用Manager字典处理并发时的注意事项。
摘要由CSDN通过智能技术生成

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值