我在尝试实施新的defaultdict
代理对象时遇到了一些麻烦。 documentation有点恐慌,所以我不知道如何正确地做这件事。Subclassing multiprocessing.managers.BaseProxy
我想将defaultdict
添加到Manager
实例可用的类型列表中。您不能使用的股票multiprocessing.Manager
的Manager.register
方法,所以我做了我自己的存根经理从multiprocessing.mangers.BaseManager
class Manager(BaseManager):
pass
然后我创造了我的multiprocessing.managers.BaseProxy
子类来容纳defaultdict
(我也开始尝试有花药存根这将子类均defaultdict
和BaseProxy
但似乎并没有工作这是我目前有:。
class ProxyDefaultDict(BaseProxy):
def __init__(self, default_factory=None, *args, **kwargs):
self.__data = defaultdict(default_factory)
super().__init__(*args, **kwargs)
def _callmethod(self, methodname, args=(), kwds={}):
return getattr(self.__data, methodname)(*args, **kwds)
def _getvalue(self):
return self.__data.copy()
def __repr__(self):
return self.__data.__repr__()
def __str__(self):
return self.__data.__str__()
Manager.register('defaultdict', ProxyDefaultDict)
的最终目标是具有安全共享跨越进程和线程键锁共享字典,他再有一个如何我的图像会被初始化的例子:
if __name__ == '__main__':
m = Manager()
d = m.defaultdict(m.Lock)
with d['named_lock']:
print('holding the lock')
不过,我已经打了几个问题:
BaseManager的一个子类似乎只是initalizable通过上下文管理器即
with Manager() as m
。在这种情况下,我将使用m = Manager()
- 因为multiprocessing.Manager
允许。不是世界末日,而是更加好奇为什么会出现这种情况,如果这是一个迹象,我正在做一些不正确的事情。子类
multiprocessing.managers.BaseManager
也menas你松开默认注册值从multiprocessing.Manager
。在这种情况下,我需要为我的经理重新注册一个ProxyLock(我也不确定预期的方式)。直接将multiprocessing.Manager
划分子类是否安全?最后,我的
ProxyDefaultDict
似乎不允许我干净地覆盖它的__init__
。我很厌倦在子类化时不打电话给BaseProxy.__init__
。问题是BaseProxy也接受位置参数。我想这种方法是使default_factory
参数只是一个键控参数,但是它将预期的接口更改为defaultdict
,并让我认为我在这里再次做错了一些事情。其他类型如Manager.Lock
似乎能够接受位置参数。
感谢您的任何帮助。
啊是啊,看起来像你可以叫''上,但SyncManager'不'Manager',感谢register'。当我尝试使用锁作为默认值时,我会得到一个不同的错误。当试图使用托管锁时,例如'm.defaultdict(m.Lock)'我得到一个'TypeError:由于安全原因'不允许腌制一个AuthenticationString对象'错误。对于非托管锁,我得到'Unserializable message:('#RETURN',)'。在Python 3.4上运行。我会想如果一个锁可以被过氧化,它可以被腌制。 –
freebie
是的,我认为3.6只是有一个更新错误/检测方法。如果我尝试使用线程锁,我会得到同样的错误。有一些其他的想法https://stackoverflow.com/questions/17960296/trouble-using-a-lock-with-multiprocessing-pool-pickling-error来解决这个问题。 – CasualDemon