繁体   English   中英

使用嵌套字典进行多处理

[英]multiprocessing with nested dictionary

有没有办法将嵌套字典传递给多处理?

d = {'a': {'x': 1, 'y':100},
     'b': {'x': 2, 'y':200}}

我希望开始两个并行作业,一个用于{'a': {'x':1, 'y':100}}另一个用于{'b': {'x': 2, 'y':200}} ,并使用以下 function 创建一个新字典

def f(d):
    key = dd.keys()
    new_d[key]['x'] = d[key]['x']*2
    new_d[key]['y'] = d[key]['y']*2

这是我不成功的尝试

import multiprocessing

def f(key, d, container):
    container[key]['x'] = d[key]['x']*2
    container[key]['y'] = d[key]['y']*2
    
if __name__ == '__main__':
    manager = multiprocessing.Manager()
    container = manager.dict()
    d = manager.dict()
    
    d['a'] = {'x': 1, 'y':100}
    d['b'] = {'x': 2, 'y':200}
        
    p1 = multiprocessing.Process(target=f, args=('a',d, container))
    p2 = multiprocessing.Process(target=f, args=('b',d, container))
    
    p1.start()
    p2.start()
    p1.join()
    p2.join()

我得到一个KeyError: 'b'而且,我想避免手动指定进程的数量,比如p1p2等等。 有没有其他方法?

嵌套的字典也必须被管理。 我在您的代码中添加了这一步,并使所有内容都依赖于d的成员,因此您不必处理p1p2等:

import multiprocessing

def f(key, d, container):
    container[key]['x'] = d[key]['x']*2
    container[key]['y'] = d[key]['y']*2

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    container = manager.dict()
    d = manager.dict()

    d['a'] = {'x': 1, 'y':100}
    d['b'] = {'x': 2, 'y':200}

    # This line initialises the nested dicts
    for key in d:
        container[key] = manager.dict()

    # Here we create a list with the processes we started
    processes = []
    for key in d:
        p = multiprocessing.Process(target=f, args=(key ,d, container))
        p.start()
        processes.append(p)

    # And finally wait for all of them to finish
    for p in processes:
        p.join()

    # Show the results
    print(container['a'])
    print(container['b'])

multiprocessing.Pool class 可能是解决您问题的更好方法(查看文档

@nonDucor 是对的:您必须使用Manager object 创建嵌套字典。

这是一个使用更多 Pythonic 字典创建以及使用ProcessPoolExecutor接口进行并发的简化解决方案:

from concurrent.futures import ProcessPoolExecutor as Executor
import multiprocessing

def f(key, d, container):
    container[key]['x'] = d[key]['x'] * 2
    container[key]['y'] = d[key]['y'] * 2

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    d = manager.dict({
        'a': manager.dict({'x': 1, 'y': 100}),
        'b': manager.dict({'x': 2, 'y': 200}),
    })
    container = manager.dict({x: manager.dict() for x in d.keys()})
    executor = Executor()
    executor.submit(f, 'a', d, container)
    executor.submit(f, 'b', d, container)
    executor.shutdown()

只是为了说明,这里是功能相同的解决方案,但这次使用多线程(通过ThreadPoolExecutor类)而不是multiprocessing 请注意,由于 memory 由两个线程共享,因此无需使用受保护的字典。 普通的 ol' dicts 就可以了:

from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor as Executor
import multiprocessing

def f(key, d, container):
    container[key]['x'] = d[key]['x'] * 2
    container[key]['y'] = d[key]['y'] * 2

if __name__ == '__main__':
    d ={
        'a': {'x': 1, 'y': 100},
        'b': {'x': 2, 'y': 200},
    }
    container = defaultdict(lambda: defaultdict(int))
    executor = Executor()
    executor.submit(f, 'a', d, container)
    executor.submit(f, 'b', d, container)
    executor.shutdown()

    print(d)
    print(container)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM