我尝试使用 BaseManager 并注册我的自定义类以使其快乐,并解决关于嵌套类的问题,正如 Tom 上面提到的那样。
我认为主要原因与所说的嵌套类无关,而是python采用低级的通信机制。原因是python使用一些类似套接字的通信机制来同步在低级别的服务器进程中对自定义类的修改。我认为它封装了一些 rpc 方法,使其对用户透明,就好像他们调用了嵌套类对象的本地方法一样。
所以,当你想修改、检索你的自定义对象或一些第三方对象时,你应该在你的进程中定义一些接口来与之通信,而不是直接获取或设置值。
但是在对嵌套对象中的多嵌套对象进行操作时,可以忽略上面提到的问题,就像您在普通例程中所做的那样,因为您在注册类中的嵌套对象不再是代理对象,对其进行操作将不再通过类似套接字的通信例程并且已本地化。
这是我为解决问题而编写的可行代码。
from multiprocessing import Process, Manager, Lock
from multiprocessing.managers import BaseManager
import numpy as np
class NestedObj(object):
def __init__(self):
self.val = 1
class CustomObj(object):
def __init__(self, numpy_obj):
self.numpy_obj = numpy_obj
self.nested_obj = NestedObj()
def set_value(self, p, q, v):
self.numpy_obj[p, q] = v
def get_obj(self):
return self.numpy_obj
def get_nested_obj(self):
return self.nested_obj.val
class CustomProcess(Process):
def __init__(self, obj, p, q, v):
super(CustomProcess, self).__init__()
self.obj = obj
self.index = p, q
self.v = v
def run(self):
self.obj.set_value(*self.index, self.v)
if __name__=="__main__":
BaseManager.register('CustomObj', CustomObj)
manager = BaseManager()
manager.start()
data = [[0 for x in range(10)] for y in range(10)]
matrix = np.matrix(data)
custom_obj = manager.CustomObj(matrix)
print(custom_obj.get_obj())
process_list = []
for p in range(10):
for q in range(10):
proc = CustomProcess(custom_obj, p, q, 10*p+q)
process_list.append(proc)
for x in range(100):
process_list[x].start()
for x in range(100):
process_list[x].join()
print(custom_obj.get_obj())
print(custom_obj.get_nested_obj())