解决python继承实现线程异常can’t pickle _thread.lock objects
问题描述
- 运行python代码
# 继承实现线程
from threading import Thread
import multiprocessing
import time
class CountdownThread(Thread):
def __init__(self, n):
super().__init__()
self.n = n
def run(self):
while self.n > 0:
print('T-minus', self.n)
self.n -= 1
time.sleep(1)
if __name__ == '__main__':
c = CountdownThread(5)
#c.run()
p = multiprocessing.Process(target=c.run)
#p.run()
p.start()
异常信息
Traceback (most recent call last):
File "f:/workspace/python workspace/python cookbook/prj12/prj12_1/src/thread5.py", line 24, in <module>
p.start()
File "F:\sdk\python\Python37\lib\multiprocessing\process.py", line 112, in start
self._popen = self._Popen(self)
File "F:\sdk\python\Python37\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "F:\sdk\python\Python37\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "F:\sdk\python\Python37\lib\multiprocessing\popen_spawn_win32.py", line 89, in __init__
reduction.dump(process_obj, to_child)
File "F:\sdk\python\Python37\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
PS F:\workspace\python workspace\python cookbook\prj12\prj12_1\src> Traceback (most recent call last):
File "<string>", line 1, in <module>
File "F:\sdk\python\Python37\lib\multiprocessing\spawn.py", line 99, in spawn_main
new_handle = reduction.steal_handle(parent_pid, pipe_handle)
File "F:\sdk\python\Python37\lib\multiprocessing\reduction.py", line 82, in steal_handle
_winapi.PROCESS_DUP_HANDLE, False, source_pid)
OSError: [WinError 87] 参数错误。
分析原因
- 主要是在多进程中,对队列的操作是使用了线程锁的,但是线程锁无法被进程打包,这种问题在spawn类型产生的进程中可以被直接的复现出来
解决方法
- 直接把进程start()方法替换为run()方法来启动就会规避这个问题
参考资料