Создайте подпроцесс из функции, принадлежащей классу, хранящему объект, который невозможно замариновать.

Я пытаюсь создать небольшой 2D-игровой движок, используя Unicurses. Для этого я создал базовый класс Player, который обрабатывает все нажатия клавиш и передает их в основную программу через канал. Однако для получения нажатий клавиш я использую функцию unicurses.wgetch(screen), которой требуется указатель на экран, созданный функцией unicurses.initscr(). Однако этот указатель, который нельзя замариновать, и поэтому возникает исключение, когда я пытаюсь создать подпроцесс (используя модуль многопроцессорной обработки), выполняющий основную функцию класса Player.

Вот пример кода, который выдает точно такую ​​же ошибку, сохраняя при этом структуру моей программы.

      import multiprocessing as mp
import unicurses as curses
from typing import Type
from multiprocessing.connection import PipeConnection
class playerbase():
    def __init__(self) -> None:
        #do something
        ...
        
    def _handshake(self, pipe:PipeConnection):
        self.pipe = pipe

    def init(self, screen):
        self.scr = screen
        #do other things
    def start(self):
        key = curses.wgetch(scr_id=self.scr)
        #do something
class engine():
    def __init__(self, player: Type[playerbase] = playerbase):
        self.player = player()
    def mainloop(self):   #gets called by the main program to start the rendering and stuff
        In, Out = mp.Pipe()
        self.player._handshake(Out)
        self.loop(In, self.player)   #I originally intended to make this a subprocess
    def loop(self, pipe:PipeConnection, player):
        stdscr = curses.initscr()
        player.init(stdscr)
        PProc = mp.Process(target=player.start, args=())
        PProc.start()

def main():
    e = engine()
    e.mainloop()
if __name__ == "__main__":
    main()

Это приводит к следующей ошибке:

      Traceback (most recent call last):
  File "[FILEPATH]", line 38, in <module>
    main()
  File "[FILEPATH]", line 36, in main
    e.mainloop()
  File "[FILEPATH]", line 26, in mainloop
    self.loop(In, self.player)   #I originally intended to make this a subprocess
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[FILEPATH]", line 32, in loop
    PProc.start()
  File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
                  ^^^^^^^^^^^^^^^^^
  File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\context.py", line 336, in _Popen
    return Popen(process_obj)
           ^^^^^^^^^^^^^^^^^^
  File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\popen_spawn_win32.py", line 94, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
ValueError: ctypes objects containing pointers cannot be pickled

0 ответов

Другие вопросы по тегам