TypeError: can't pickle _thread.RLock objects

"D:\Program Files\Python36\python.exe" E:/工作文件/Project/pycrontab/test.py
Traceback (most recent call last):
  File "E:/工作文件/Project/pycrontab/test.py", line 9, in 
    crontab_run(True)
  File "E:\工作文件\Project\pycrontab\pycrontab.py", line 275, in crontab_run
    p.start()
  File "D:\Program Files\Python36\lib\multiprocessing\process.py", line 105, in start
    self._popen = self._Popen(self)
  File "D:\Program Files\Python36\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "D:\Program Files\Python36\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "D:\Program Files\Python36\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "D:\Program Files\Python36\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _thread.RLock objects

强调内容*Python中使用多线程模块开发时,如果把一个使用了_thread.RLock的对象put到Queue队列里时,就会报这个错。比如logging模块。因为放进队列里的对象都要被序列化,而_thread.RLock不能被序列化。另外文件对象也能被序列化。

Note When an object is put on a queue, the object is pickled and a background thread later flushes the pickled data to an underlying pipe. This has some consequences which are a little surprising, but should not cause any practical difficulties – if they really bother you then you can instead use a queue created with a manager.

所以,我们可以使用manager来解决该问题。如:

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    manager = Manager()

    d = manager.dict()
    l = manager.list(range(10))

    p = Process(target=f, args=(d, l))
    p.start()
    p.join()

    print d
    print l

manager的使用方法见官方文档:https://docs.python.org/2/library/multiprocessing.html#managers

如果还不能解决问题,就需要重写__getstat____setstat__方法以改变序列化方式

你可能感兴趣的:(Python)