Исключение «Can't pickle class ...» возникает при назначении данных самому себе в пределах Python worker - PullRequest
0 голосов
/ 28 мая 2020

У меня очень странная ситуация, когда запуск рабочего через multiprocessing завершается неудачно со следующим исключением:

_pickle.PicklingError: Can't pickle <class 'c_ubyte_Array_4_Array_80_Array_80'>: attribute lookup c_ubyte_Array_4_Array_80_Array_80 on __main__ failed

Минимальный код воспроизведения следующий:

import multiprocessing as mp
import numpy as np
from multiprocessing import sharedctypes


class Worker(mp.Process):
    def __init__(self,
                data):
        super(Worker, self).__init__()
        self.data = data # <<==== IF I ADD THIS TO THE WORKER, IT FAILS WITH THE EXCEPTION BELOW
        print('Im running!')

def main():
    tmp = np.ctypeslib.as_ctypes(np.zeros((4,80,80,4), dtype=np.uint8))
    data = sharedctypes.Array(tmp._type_, tmp, lock=False) 

    worker = Worker(data)
    worker.start()

if __name__ == '__main__':
    main()

I Я запускаю его с Python 3, с Windows 10. Если я удалю это собственное назначение, где я назначаю self.data = data, код будет выполнен. Когда я добавляю это задание, я получаю следующую ошибку:

Im running!
Traceback (most recent call last):
  File "issue.py", line 22, in <module>
    main()
  File "issue.py", line 19, in main
    worker.start()
  File "C:\Program Files\Python37\lib\multiprocessing\process.py", line 112, in start
    self._popen = self._Popen(self)
  File "C:\Program Files\Python37\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Program Files\Python37\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "C:\Program Files\Python37\lib\multiprocessing\popen_spawn_win32.py", line 89, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Program Files\Python37\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <class 'c_ubyte_Array_4_Array_80_Array_80'>: attribute lookup c_ubyte_Array_4_Array_80_Array_80 on __main__ failed

Что я делаю не так, если что-то не так, и как это исправить? Я на связи Python 3.7

Спасибо!

Эдуардо

...