【发布时间】:2019-09-04 13:26:06
【问题描述】:
我尝试在一个类中使用 Multiprocessing。我使用 Multiprocessing.pipe() 将实例 o 从父进程传递到子进程。
self.listofwritetags = self.collectwritetaglist()
self.progressbar['value'] = 20
self.frame.update_idletasks()
self.alldevice = alldevices_V3.AllDevices(self.comm_object)
self.progressbar['value'] = 40
self.frame.update_idletasks()
con1,con2 = multiprocessing.Pipe()
con1.send(self.alldevice)
con2.send(self.comm_object)
# Multithreading section
# self.callmotor1dprocess = thread_with_trace(target=self.callallmotor1d,args=(self.comm_object,self.alldevice))
self.callmotor1dprocess = multiprocessing.Process(target = self.callallmotor1d,args= (con1,con2))
self.listofthread.append(self.callmotor1dprocess)
self.button2.config(text="Initialized")
initial = "True"
self.progressbar.stop()
现在我调用所有的多处理启动
def startprocess(self):
for item in self.listofthread:
item.start()
self.button3.config(text="started")
def stopprocess(self):
for item in self.listofthread:
item.kill()
我在类内调用此代码。现在我应该在类外调用已执行的方法。
def callallmotor1d(con1,con2):
comobject = con1.recv()
devices = con2.recv()
while True:
Allmotorprocessing.process(comobject, devices)
但是我得到了一个很常见的错误:- 错误信息:-
Traceback(最近一次调用最后一次): _feed 中的文件“C:\Users\misu01\AppData\Local\Programs\Python\Python37\lib\multiprocessing\queues.py”,第 236 行 obj = _ForkingPickler.dumps(obj) 转储中的文件“C:\Users\misu01\AppData\Local\Programs\Python\Python37\lib\multiprocessing\reduction.py”,第 51 行 cls(buf, 协议).dump(obj) TypeError:无法腌制 _thread.lock 对象 回溯(最近一次通话最后): _feed 中的文件“C:\Users\misu01\AppData\Local\Programs\Python\Python37\lib\multiprocessing\queues.py”,第 236 行 obj = _ForkingPickler.dumps(obj) 转储中的文件“C:\Users\misu01\AppData\Local\Programs\Python\Python37\lib\multiprocessing\reduction.py”,第 51 行 cls(buf, 协议).dump(obj) TypeError: can't pickle _thread.lock objects
我不知道为什么要创建 thread.lock 对象。 为了避免这个错误,我尝试像这样修改我的 Alldevices 类和 comm_object 类:-
这是我的修改:-
类 AllDevices:
def __init__(self,comobject):
self.mylock = threading.Lock()
self.comobject = comobject
self.dfM1D = pd.read_excel(r'C:\OPCUA\Working_VF1_5.xls', sheet_name='Motor1D')
self.allmotor1dobjects = callallmotor1D_V3.Cal_AllMotor1D(self.dfM1D, self.comobject)
def __getstate__(self):
state = vars(self).copy()
# Remove the unpicklable entries.
del state['mylock']
return state
def __setstate__(self, state):
# Restore instance attributes.
vars(self).update(state)
这里是 comobject 类。
class General():
def __init__(self):
self.client = Communication()
self.mylock = threading.Lock()
self.sta_con_plc = self.client.opc_client_connect()
self.readgeneral = ReadGeneral(self.client.PLC)
self.writegeneral = WriteGeneral(self.client.PLC)
def __getstate__(self):
state = vars(self).copy()
# Remove the unpicklable entries.
del state['mylock']
return state
def __setstate__(self, state):
# Restore instance attributes.
vars(self).update(state)
但我还是遇到了错误。
这是我的实现是否正确?
self.allmotor1dobjects = callallmotor1D_V2.Cal_AllMotor1D(self.dfM1D, self.comobject,self.logger)
这里 self.allmotor1dobjects 也是类实例。
喜欢:-
self.client = Communication()
self.readgeneral = ReadGeneral(self.client.PLC)
self.writegeneral = WriteGeneral(self.client.PLC)
这些也是类实例。
我从未使用过 thread.lock 这两个类中的任何一个。 我不知道它是如何创建的。
根据文档建议https://docs.python.org/3/library/pickle.html#pickling-class-instances 如果我使用 getstate 和 setstate,它应该会消除此错误。
在我的情况下它不起作用。
如何消除此错误。
我们将非常感谢您在这方面的任何帮助
【问题讨论】:
-
什么是
devices?好像它们包含线程锁作为属性,不能腌制。 -
devices 是一个类对象......类名是 alldevices 可以初始化一些基本配置的东西。所以我不能通过管道传递一个类的对象
-
通常可以,但如果它们具有不可腌制的实例属性并且没有覆盖腌制行为以避免腌制它们,则不能。我已经发布了包含一些可能修复的答案,但对
alldevice或您的具体用例一无所知,我无法给出具体答案。 -
@SM2019 问题不在于你的对象是一个“类对象”(它不是,这意味着它是一个类,你的意思是一个 instance类,但 everything 是 Python 中类的实例)。问题是你的对象不能被腌制。
-
@ juanpa.arrivillaga ,谢谢你我现在明白了。
标签: python python-3.x ipc pickle python-multiprocessing