【问题标题】:Unable to update nested dictionary value in multiprocessing's manager.dict()无法更新多处理的 manager.dict() 中的嵌套字典值
【发布时间】:2026-01-10 20:45:01
【问题描述】:

我正在尝试更新多处理模块 manager.dict() 的嵌套字典中的键,但无法这样做。它不会更新值,也不会抛出任何错误。

代码:

import time
import random
from multiprocessing import Pool, Manager

def spammer_task(d, token, repeat):
    success = 0
    fail = 0
    while success+fail<repeat:
        time.sleep(random.random()*2.0)
        if (random.random()*100)>98.0:
            fail+=1
        else:
            success+=1
        d[token] = {
            'status': 'ongoing',
            'fail': fail,
            'success': success,
            'repeat': repeat
        }
    print d[token]['status']
    d[token]['status'] = 'complete'
    return

p = Pool()
m = Manager()
d = m.dict()

p.apply_async(spammer_task (d, 'abc', 5))
print d

输出:

进行中

{'abc': {'status': 'ongoing', 'fail': 0, 'repeat': 5, 'success': 5}}

我的期望是,一旦 while 循环结束,它应该使 d['abc']['status'] = 完成。但在最终打印时,它仅将其状态打印为“正在进行”。

【问题讨论】:

    标签: python dictionary multiprocessing python-multiprocessing multiprocessing-manager


    【解决方案1】:

    不知道为什么,但是 Manager DictProxy 对象似乎无法处理嵌套部分的变异。此代码有效:

    import time
    import random
    from multiprocessing import Pool, Manager
    
    def spammer_task(d, token, repeat):
        success = 0
        fail = 0
        while success+fail<repeat:
            time.sleep(random.random()*2.0)
            if (random.random()*100)>98.0:
                fail+=1
            else:
                success+=1
            d[token] = {
                'status': 'ongoing',
                'fail': fail,
                'success': success,
                'repeat': repeat,
            }
        print d[token]['status']
        foo = d[token]
        foo['status'] = 'complete'
        d[token] = foo
        return
    
    p = Pool()
    m = Manager()
    d = m.dict()
    
    p.apply_async(spammer_task(d, 'abc', 5))
    print d
    

    【讨论】:

    • 谢谢,没有其他使用额外内存的解决方案吗?我将在 HTTP 服务器内对这个多处理器进行去魔化处理,并且不想为它们处理额外的内存 + 清理。
    • 根据文档这部分下的注释:docs.python.org/2/library/… - 以上似乎是建议的方法。
    • @domoarrigato 发布的注释已过时 - 但官方 Python 文档确实声明此答案是正确的。这是新链接 - 向下滚动一点即可找到“注释”:docs.python.org/2/library/multiprocessing.html#managers
    【解决方案2】:

    看起来这个问题仍然存在于下面的代码中:

    import multiprocessing, sys;
    
    if __name__ == '__main__':
    
    print(sys.version);
    
    mpd = multiprocessing.Manager().dict();
    mpd['prcss'] = {'q' : 'queue_1', 'ctlg' : 'ctlg_1' };
    
    # update 1 - doesn't work!
    mpd['prcss'].update( { 'name': 'concfun_1'} );
    print('Result of failed update 1:', mpd['prcss']);
    
    # update 2 - doesn't work!
    mpd['prcss']['name'] = 'concfun_1';
    print('Result of failed update 2:', mpd['prcss']);
    
    # update 3 - works!
    mpd_prcss = mpd['prcss'];
    mpd_prcss['name'] = 'concfun_1';
    mpd['prcss'] = mpd_prcss;
    print('Result of successful update 3:', mpd['prcss']);
    

    输出:

    3.6.1(v3.6.1:69c0db5,2017 年 3 月 21 日,17:54:52)[MSC v.1900 32 位(英特尔)]

    更新 1 失败的结果:{'q': 'queue_1', 'ctlg': 'ctlg_1'}

    更新 2 失败的结果:{'q': 'queue_1', 'ctlg': 'ctlg_1'}

    成功更新 3 的结果:{'q': 'queue_1', 'ctlg': 'ctlg_1', '名称': 'concfun_1'}

    【讨论】: