我在与multiprocessing
共享对象实例字典时遇到问题。我试图使用一个dict
,它被manager
共享,但是当我试图使用对象实例作为键时,它会被复制。在
import multiprocessing
class Dog():
def __init__(self, name = "joe"):
self.name = name
def bark(self):
print("woof")
mg = multiprocessing.Manager()
dt = mg.dict()
dt["a"] = 1
dt["b"] = 2
# As expected
print(dt.items()) # => [('a', 1), ('b', 2)]
dt = mg.dict()
lab = Dog("carl")
print(lab) # => <__main__.Dog instance at 0x7f8d6bb869e0>
dt[lab] = 1
# But then I don't get the ID I expect
print(dt.items()) # => [(<__main__.Dog instance at 0x7f8d6bb86908>, 1)]
我知道解决这个问题的方法是使用对象ID作为键,但是为什么会发生这种情况呢?使用对象ID是解决我问题的最佳方法吗?我注意到,普通的非manager
dict()
对象不会发生这种情况。在
In the documentation for ^{
如the documentation on managers所述:
尽管
multiprocessing
使多个进程之间的通信变得容易,但它仍然不能执行操作系统不允许的操作(访问另一个进程的内存)。实际上,Manager
的工作是处理对象的副本,这些副本在需要时被序列化。在请注意,您将无法在其他进程中获取这些对象实例。 “正确”的方法是在更改对象时重新指定它们。在
当您创建
multiprocessing.Manager
时,将产生一个单独的服务器进程,该进程负责托管Manager
创建的所有对象。因此,为了将Dog
实例存储在Manager
dict
中,需要对该实例进行pickle并将其发送到Manager
进程。当然,这会导致在Manager
进程中创建一个完全独立的Dog
实例,因此它的ID将与父进程中的Dog
实例的ID不匹配。除了在Manager
中创建Dog
实例作为Proxy
实例之外,没有其他方法可以避免:输出:
^{pr2}$请记住,这将使对父进程中的
Dog
实例的所有访问变慢,因为它们现在需要对Manager
进程进行IPC调用。在相关问题 更多 >
编程相关推荐