首页 > 解决方案 > 使用 python 对象进行多处理

问题描述

我一直在做遗传算法来解决简单的 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(),但它给出了以下错误:

TypeError: *: 'type' 和 '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

标签: pythonmultiprocessingpython-multiprocessinggenetic-algorithm

解决方案


推荐阅读