Многопроцессорная обработка с использованием объектов python

#python #multiprocessing #python-multiprocessing #genetic-algorithm

Вопрос:

Я разрабатывал генетический алгоритм для решения простых уровней 2D-платформера. Теперь я хочу добавить многопроцессорную обработку для параллельного выполнения «обновления» моей совокупности, но мне не удалось заставить ее работать, так как все рабочие примеры, которые я нашел, относятся к простым массивам, даже с общей памятью, и мне нужно работать с вложенными объектами и общей памятью.

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

         # divide players for processes
        splits = np.array_split(groups.players_group, settings.PROCESSES)

        # create processes
        processes = []
        for i in range(settings.PROCESSES):
            p = mp.Process(target=update_players, args=(splits[i],))
            processes.append(p)
            processes[i].start()
        
        # join processes (wait for 'em to finish)
        for p in processes:
            p.join()
 

Теперь ошибки не были ясны, так как теперь у них просто возникают проблемы с поиском объектов (в журналах говорится, что есть пустые объекты, которые не обладают каким-либо необходимым свойством для процесса обновления, хотя на самом деле они должны его иметь. Поэтому я начинаю верить, что проблема связана с общей памятью, которую я не знаю, как применить к объектам python).

[ПРАВИТЬ]

Я попытался обернуть свои списки объектов с multiprocessing.Array() помощью , но это приводит к следующей ошибке:

Ошибка типа: неподдерживаемые типы операндов для*: «тип» и «int»

Также… вот функция «обновить игроков» :

 def update_players(players, ret_queue):
        for p in players:
            p.update()
            ret_queue.put(players)
 

и, как вы можете видеть , он звонит Player.Update() , что безумно долго, но вот он на случай, если вы захотите его проверить:

 def update(self):
        if not self.is_dead and not self.reached_goal and not self.finished:
            # act according to brain if necessary
            if self.is_ai:
                # reset movements
                self.releaseLeft()
                self.releaseRight()
                if self.brain_step >= len(self.brain.instructions):
                    if not self.reached_goal and not self.isMoving():
                        self.finished = True
                else:
                    self.executeNextBrainStep()

            self.rect.y  = self.y_spd
            self.y_spd  = self.gravity

            # check if player is colliding with floor
            for tile in groups.floor_tiles:
                if helpers.rectsColliding(self.rect, tile.rect):
                    # check vertical collision
                    if self.rect.getCenterY() < tile.rect.y:  # from top
                        self.y_spd = 0
                        self.rect.y = tile.rect.y - self.rect.height   1
                        self.is_jumping = False
                    # from bottom
                    elif self.rect.getCenterY() > (tile.rect.y   tile.rect.height):
                        self.y_spd = 0
                        self.rect.y = tile.rect.y   tile.rect.height

                    # check horizontal collision
                    #   should be within same vertical space
                    if self.rect.getCenterY() >= (tile.rect.getCenterY() - tile.rect.height/3):
                        if self.rect.getCenterY() <= (tile.rect.getCenterY()   tile.rect.height/3):
                            # now we can check the horizontal collision
                            if self.rect.getCenterX() < tile.rect.x:  # from left
                                self.right = 0
                                self.rect.x = tile.rect.x - self.rect.width
                            # from right
                            elif self.rect.getCenterX() > (tile.rect.x   tile.rect.width):
                                self.left = 0
                                self.rect.x = tile.rect.x   tile.rect.width

            self.dir = (self.right - self.left)
            self.rect.x  = self.dir * self.walk_spd

            # check if dead
            if self.rect.x > settings.SCR_W or (self.rect.x   self.rect.width) < 0:
                self.is_dead = True
                self.finished = True
            if self.rect.y > settings.SCR_H or (self.rect.y   self.rect.height) < 0:
                self.is_dead = True
                self.finished = True

            # if optimizing, check if should stop
            if settings.OPTIMIZATION_FITNESS:
                self_dist = helpers.dist_modular(self.rect.x, settings.goal.rect.x, self.rect.y, settings.goal.rect.y)
                best_dist = helpers.dist_modular(settings.BEST_X, settings.goal.rect.x, settings.BEST_Y, settings.goal.rect.y)
                if self_dist < best_dist:
                    self.finished = True
                    self.reached_goal = True

            # check if reached goal
            if helpers.objectsColliding(self, settings.goal):
                self.reached_goal = True
                self.finished = True
 

И на случай, если кто-нибудь из вас захочет проверить репо, вот оно: https://github.com/santyarellano/GeneticLevelTester

Комментарии:

1. вы можете поделиться функцией update_players?

2. да, я добавлю это в главный вопрос

3. У update_players есть два символа, которые вы передаете только одному.

4. да… это было то, что я пробовал, но это не то :/