RuntimeError: объекты очереди должны быть общими только для процессов через наследование - PullRequest
1 голос
/ 31 марта 2020

У меня проблемы с ProcessPoolExecutor. Следующий код пытается найти кратчайший путь в игре WikiRace, он получает 2 заголовка и перемещается между ними.

Вот мой код:

class AsyncSearch:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        # self.manager = multiprocessing.Manager()
        self.q = multiprocessing.Queue()
        # self.q = self.manager.Queue()

    def _add_starting_node_page_to_queue(self):
        start_page = WikiGateway().page(self.start)
        return self._check_page(start_page)

    def _is_direct_path_to_end(self, page):
        return (page.title == self.end) or (page.links.get(self.end) is not None)

    def _add_tasks_to_queue(self, pages):
        for page in pages:
            self.q.put(page)

    def _check_page(self, page):
        global PATH_WAS_FOUND_FLAG
        logger.info('Checking page "{}"'.format(page.title))
        if self._is_direct_path_to_end(page):
            logger.info('##########\n\tFound a path!!!\n##########')
            PATH_WAS_FOUND_FLAG = True
            return True
        else:
            links = page.links
            logger.info("Couldn't find a direct path form \"{}\", "
                        "adding {} pages to the queue.".format(page.title, len(links)))
            self._add_tasks_to_queue(links.values())
            return "Couldn't find a direct path form " + page.title

    def start_search(self):
        global PATH_WAS_FOUND_FLAG
        threads = []
        logger.debug(f'Running with concurrent processes!')
        if self._add_starting_node_page_to_queue() is True:
            return True
        with concurrent.futures.ProcessPoolExecutor(max_workers=AsyncConsts.PROCESSES) as executor:
            threads.append(executor.submit(self._check_page, self.q.get()))

Я получаю следующее исключение:

Traceback (most recent call last):
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\queues.py", line 241, in _feed
    obj = _ForkingPickler.dumps(obj)
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\queues.py", line 58, in __getstate__
    context.assert_spawning(self)
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\context.py", line 356, in assert_spawning
    ' through inheritance' % type(obj).__name__
RuntimeError: Queue objects should only be shared between processes through inheritance

Это странно, так как я использую multiprocessing.Queue(), который должен быть разделен между процессами, как указано в исключении.

Я нашел этот похожий вопрос , но не смог найти там ответа.

Я пытался использовать self.q = multiprocessing.Manager().Queue() вместо self.q = multiprocessing.Queue(), я не уверен, если это берет меня куда угодно, но исключение, которое я получаю, отличается:

Traceback (most recent call last):
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\queues.py", line 241, in _feed
    obj = _ForkingPickler.dumps(obj)
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
  File "c:\users\tomer smadja\appdata\local\programs\python\python36-32\lib\multiprocessing\process.py", line 282, in __reduce__
    'Pickling an AuthenticationString object is '
TypeError: Pickling an AuthenticationString object is disallowed for security reasons

Кроме того, когда я пытаюсь использовать multiprocessing.Process() вместо ProcessPoolExecutor, я не могу завершить sh процесс, как только я найду путь. Я установил глобальную переменную для остановки PATH_WAS_FOUND_FLAG, чтобы остановить запуск процесса, но все еще безуспешно. Что мне здесь не хватает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...