[英]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'
而且,我想避免手动指定进程的数量,比如p1
和p2
等等。 有没有其他方法?
嵌套的字典也必须被管理。 我在您的代码中添加了这一步,并使所有内容都依赖于d
的成员,因此您不必处理p1
、 p2
等:
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.