Python class 中的多处理共享字典
Python multiprocessing shared dict inside a class
我想了解多处理和管理器如何工作以共享内存
我有一个 class,在 class 上创建了一个字典。init
我想使用多处理来调用填充字典的 class 函数(每个进程添加一个不同的键)。
import multiprocessing as mp
from multiprocessing import Process, Manager
class num:
def __init__(self):
manager = Manager()
d = manager.dict()
# Setup list of processes
processes = [mp.Process(target=self.f, args=(d,i)) for i in range(5)]
#Run processes
for p in processes:
p.start()
#Exit the completed processes
for p in processes:
p.join()
print d
def f(self,d,i):
d[str(i)] = []
d[str(i)].append(i)
if __name__ == '__main__':
test = num()
结果:
{'1': [], '0': [], '3': [], '2': [], '4': []}
f()里面的列表也需要共享?如何以及为什么?
您需要将函数 f
中的行更改为:
d['i'] = [i]
类似于
d[str(i)] = i
这样您的进程就不会覆盖彼此在共享字典中的条目。之后,它对我来说工作正常(在 Python 2.7.3 中),打印出
{'1': 1, '0': 0, '3': 3, '2': 2, '4': 4}
(此外,您发布的代码缺少 import multiprocessing as mp
)
更新:如果你只是想让共享字典中的值成为列表,那么这是一个简单的改变,例如
d[str(i)] = [i]
如果您希望每个列表在所有进程之间共享,那么您可能需要在主进程中创建这些列表,使用 manager.list()
,然后将它们传递给所有子进程,例如:
count = 5
lists = [manager.list() for i in range(count)]
for i in range(count):
d[i] = lists[i]
processes = [mp.Process(target=self.f, args=(d,i, lists)) for i in range(count)]
[...]
def f(self,d,i, lists):
for j in range(i): # just an example to show
lists[j].append(i) # that the lists are shared between processes
我也试过直接将托管列表嵌套在托管字典中,但由于某种原因这不起作用,子进程无法更新列表。如图所示分别传递它们似乎有效,例如我可以让每个子进程更新多个列表:
{0: [1, 2, 3, 4], 1: [2, 3, 4], 2: [3, 4], 3: [4], 4: []}
正在替换:
d[str(i)].append(i)
与:
d[str(i)] += [i]
解决问题。
结果:
{'1': [1], '0': [0], '3': [3], '2': [2], '4': [4]}
但我真的很想知道为什么。
我想了解多处理和管理器如何工作以共享内存
我有一个 class,在 class 上创建了一个字典。init 我想使用多处理来调用填充字典的 class 函数(每个进程添加一个不同的键)。
import multiprocessing as mp
from multiprocessing import Process, Manager
class num:
def __init__(self):
manager = Manager()
d = manager.dict()
# Setup list of processes
processes = [mp.Process(target=self.f, args=(d,i)) for i in range(5)]
#Run processes
for p in processes:
p.start()
#Exit the completed processes
for p in processes:
p.join()
print d
def f(self,d,i):
d[str(i)] = []
d[str(i)].append(i)
if __name__ == '__main__':
test = num()
结果:
{'1': [], '0': [], '3': [], '2': [], '4': []}
f()里面的列表也需要共享?如何以及为什么?
您需要将函数 f
中的行更改为:
d['i'] = [i]
类似于
d[str(i)] = i
这样您的进程就不会覆盖彼此在共享字典中的条目。之后,它对我来说工作正常(在 Python 2.7.3 中),打印出
{'1': 1, '0': 0, '3': 3, '2': 2, '4': 4}
(此外,您发布的代码缺少 import multiprocessing as mp
)
更新:如果你只是想让共享字典中的值成为列表,那么这是一个简单的改变,例如
d[str(i)] = [i]
如果您希望每个列表在所有进程之间共享,那么您可能需要在主进程中创建这些列表,使用 manager.list()
,然后将它们传递给所有子进程,例如:
count = 5
lists = [manager.list() for i in range(count)]
for i in range(count):
d[i] = lists[i]
processes = [mp.Process(target=self.f, args=(d,i, lists)) for i in range(count)]
[...]
def f(self,d,i, lists):
for j in range(i): # just an example to show
lists[j].append(i) # that the lists are shared between processes
我也试过直接将托管列表嵌套在托管字典中,但由于某种原因这不起作用,子进程无法更新列表。如图所示分别传递它们似乎有效,例如我可以让每个子进程更新多个列表:
{0: [1, 2, 3, 4], 1: [2, 3, 4], 2: [3, 4], 3: [4], 4: []}
正在替换:
d[str(i)].append(i)
与:
d[str(i)] += [i]
解决问题。
结果:
{'1': [1], '0': [0], '3': [3], '2': [2], '4': [4]}
但我真的很想知道为什么。