如何在进程分叉时共享对象树?
我对多线程的经验不多,现在想实现下面这样的功能:
from multiprocessing import Process
class Node:
def __init__(self):
self.children = {}
class Test(Process):
def __init__(self, tree):
super().__init__()
self.tree = tree
def run(self):
# infinite loop which does stuff to the tree
self.tree.children[1] = Node()
self.tree.children[2] = Node()
x = Node()
t = Test(x)
t.start()
print(x.children) # random access to tree
我知道这样做是行不通的,原因也很合理,但我不太清楚该怎么才能让它工作。查阅文档后,我发现需要用到管理器和代理,但老实说,我不知道从哪里开始,也不确定这是否是我真正需要的。有人能给我一个能工作的例子吗?
2 个回答
2
我觉得你想要的是多线程,而不是多进程。使用线程而不是进程,你可以实现这个目标,因为线程是在同一个进程中运行的,它们可以共享所有的内存和数据。
2
multiprocessing
对于一些可以共享的对象支持有限,这些对象甚至可以是列表和字典。
一般来说,multiprocessing
是一种“共享无物”的方式(在最开始的分叉之后),它依赖于进程之间的明确通信。这会增加一些额外的开销(具体多少取决于进程之间的交互方式),但这样可以避免多线程编程中的许多麻烦。multiprocessing
的高级构建块更倾向于主从模型(特别是 Pool类),主进程负责分配任务,从进程则执行这些任务并返回结果。
在多个进程之间保持状态同步,可能会因为状态变化的频率而导致很大的开销。
总结: 这可以做到,但可能不太应该这样做。
import time, multiprocessing
class Test(multiprocessing.Process):
def __init__(self, manager):
super().__init__()
self.quit = manager.Event()
self.dict = manager.dict()
def stop(self):
self.quit.set()
self.join()
def run(self):
self.dict['item'] = 0
while not self.quit.is_set():
time.sleep(1)
self.dict['item'] += 1
m = multiprocessing.Manager()
t = Test(m)
t.start()
for x in range(10):
time.sleep(1.2)
print(t.dict)
t.stop()
multiprocessing
的示例展示了如何为更复杂的对象创建代理,这应该能帮助你实现你问题中的树结构。