无法在多处理中共享类

问题描述 投票:0回答:1

我正在尝试创建一个在 Python 3 多处理中共享给定类对象的测试程序。

为此,我首先创建一个类对象,然后对其应用 manager.Value 以获取共享对象。

问题在于共享对象在进程外部和进程内部的内存中似乎不是同一个对象。

知道我做错了什么吗?

应用程序代码是:

class MyClass:
    def __init__(self, val):
        self.val = val

    def set(self, val):
        print(f'set({val})')
        self.val= val

    def get(self):
        return self.val

def modify(args):
    shared, v = args
    print(f'prev, get()= {shared.value.get()}')
    shared.value.set(v)
    print(f'after, get()= {shared.value.get()}')

def main5():
    manager = Manager()
    myclass = MyClass(-1)
    shared = manager.Value('c', myclass)
    pool = Pool(1)
    params = []
    for v in range(5, 6):
        params.append((shared, v))
    pool.imap(func=modify, iterable=params)
    pool.close()
    pool.join()

    print("Valor modificado:", shared.value.get())

if __name__ == '__main__':
    freeze_support()
    main5()

输出为:

prev, get()= -1
set(5)
after, get()= -1
Last value stored: -1
python-3.x multiprocessing
1个回答
0
投票

问题在于如何共享对象以及 multiprocessing.Value 的限制。 让我们分解问题并提出解决方案:

  1. 多处理。值限制: 值旨在共享基本数据类型,例如整数、字符和这些类型的数组。它并不意味着共享复杂的对象,例如自定义类实例。 当您使用 manager.Value('c', myclass) 时,它会尝试存储对象的表示形式,而不是实际的对象本身。这种表示可能只包括对象的初始状态,而不包括其方法或行为。
  2. 共享复杂对象: 要跨进程共享 MyClass 实例等复杂对象,您需要保留对象行为和状态的机制。这里有两个选择:

a) 使用 multiprocessing.Manager().Namespace(): 命名空间就像跨进程共享的字典。您可以将 MyClass 实例存储为此共享字典中的值。

def main5():
    manager = Manager()
    shared_namespace = manager.Namespace()
    myclass = MyClass(-1)
    shared_namespace.myclass_instance = myclass  # Store the instance
    # ... rest of the code using shared_namespace.myclass_instance ...

b) 使用 multiprocessing.Queue: 您可以通过队列将整个 MyClass 实例发送到子进程。这允许子进程拥有自己的对象副本,但可能比共享内存效率低。

def modify(q, v):
    myclass_instance = q.get()  # Receive the instance
    # ... work with myclass_instance ...

def main5():
    # ...
    q = Queue()
    q.put(myclass)  # Send the instance
    pool.apply_async(modify, args=(q, v))
    # ...

如果有帮助请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.