如何在进程分叉时共享对象树?

1 投票
2 回答
508 浏览
提问于 2025-04-17 19:50

我对多线程的经验不多,现在想实现下面这样的功能:

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 的示例展示了如何为更复杂的对象创建代理,这应该能帮助你实现你问题中的树结构。

撰写回答