【发布时间】:2021-01-02 12:15:42
【问题描述】:
所以我试图通过网络共享对自定义类对象的访问,方法是让主机为其提供服务,并且多个客户端连接并更新它。似乎标准多处理库仅针对此用例提供了管理器和代理。
我相信通过阅读多处理 docs (and other posts here) 在主机端我需要一个从多处理 BaseManager 类派生的自定义管理器,然后使用自定义注册我的自定义类从多处理 BaseProxy 类派生的代理。我相信在客户端我需要连接到管理器并使用代理与我的自定义类进行交互。
我遇到的问题是,在我的自定义类的主机版本上更改的属性在客户端上看不到,反之亦然。看来我在实现上做错了或误解了文档/源代码。有人可以帮忙提供一个工作示例并解释解决方案吗?
这是我的最小示例。
在一个终端中运行管理器:
>> python -i manager.py
from multiprocessing.managers import BaseManager, BaseProxy, MakeProxyType
IP = 'localhost'
PORT = 50000
KEY = b'abracadabra'
# shared class
class Foo:
"""my custom shared class"""
def __init__(self):
self.x = None
def get_x(self):
return self.x
def set_x(self, value):
self.x = value
# proxy class
FooProxyBase = MakeProxyType('FooProxyBase', ('get_x', 'set_x'))
class FooProxy(FooProxyBase):
"""shared class proxy"""
def get_x(self):
return self._callmethod('get_x')
def set_x(self, value):
return self._callmethod('set_x', (value,))
# custom shared class manager
class MyBaseManager(BaseManager):
pass
# manager, run manager server for shared class and set data
print(f'manager running on proc {os.getpid()}')
MyBaseManager.register("Foo", Foo, FooProxy)
m = MyBaseManager(address=(IP, PORT), authkey=KEY)
m.start()
print(f'manager server running on proc {m._process.pid}')
print(f'(proxy) {str(m)}')
print(f'(referant) {repr(m)}')
# get copy of managed class proxy and set value to 10
f = m.Foo()
print(f'x={f.get_x()} => should be None')
f.set_x(10) # set x value to 10
print(f'x={f.get_x()} => should be 10')
在其他终端运行客户端
>> python -i client.py
from multiprocessing.managers import BaseManager, BaseProxy, MakeProxyType
IP = 'localhost'
PORT = 50000
KEY = b'abracadabra'
# proxy class
FooProxyBase = MakeProxyType('FooProxyBase', ('get_x', 'set_x'))
class FooProxy(FooProxyBase):
"""shared class proxy"""
def get_x(self):
return self._callmethod('get_x')
def set_x(self, value):
return self._callmethod('set_x', (value,))
# custom shared class manager
class MyBaseManager(BaseManager):
pass
# client, connect to manager server and get data from shared class
print(f'client running on proc {os.getpid()}')
MyBaseManager.register("Foo", None, FooProxy)
m = MyBaseManager(address=(IP, PORT), authkey=KEY)
m.connect()
print(f'(proxy) {str(m)}')
print(f'(referant) {repr(m)}')
# get copy of managed class proxy and get value, should be 10
f = m.Foo()
print(f'x={f.get_x()} => should be 10')
您将看到客户端在 x=None 应该为 10 时返回。我没有收到明显的异常,并且在 Ubuntu 18 和 OSX 上进行了尝试并获得了相同的行为。
请注意,我仅限于 python 3.6 和在我的生产系统上使用标准库。我还成功尝试了多处理文档中的其他示例,因此请相信这不是计算机/网络问题。
谢谢
【问题讨论】:
标签: python-3.x multiprocessing python-multiprocessing