进程间数据共享问题

1 投票
1 回答
812 浏览
提问于 2025-04-16 16:04

我刚接触Python,正在做一个多进程的示例脚本。代码大约有100行,你可以在这里找到它 - http://pastie.org/1813365

这个游戏很简单,发生在方形的场地上 - 它们用矩阵表示(就是一个包含多个列表的列表,每个列表里有相同数量的元素)。每个玩家都有一个单独的游戏场地。

我创建的每个进程代表一个玩家。每轮游戏中,每个“玩家”会随机生成两个坐标和一个数字(0到9之间)。每个“玩家”尝试在自己的坐标上放置这个数字;如果在其他玩家的场地上这些坐标没有数字,或者这个数字小于第一个玩家的数字,或者第一个玩家的数字是‘0’(就像一张‘万能牌’) - 那么这个数字就会被放置在两个场地上,并且玩家的得分会增加。游戏在指定的轮数后结束。

所有的数据都存储在一个包含数据的对象中,这个对象从主线程传递到“第一个玩家”的线程,然后在游戏进行中不断在各个线程之间传递,来回交换,直到游戏结束。为此使用了‘JoinableQueue’。

代码的问题在于,每个“玩家”似乎都有自己独立的游戏场地副本。如果你在每轮游戏中输出两个玩家的游戏场地,你会发现它们是完全相同的。例如,注释掉的那行代码没有效果,因为另一个玩家(在他回合时打印的)的场地从未被修改:

if x.data_PC[y2][x2] == 'X' or z2 == 0 or int(x.data_PC[y2][x2]) < z2:         
    x.data_PC2[y2][x2] = str(z2) # doesn't work
    x.data_PC[y2][x2] = str(z2)
    x.score_PC2 += 1

这尤其奇怪,因为对象中的其他数据似乎都正常工作。

是什么导致了这种情况,我该如何解决呢?

1 个回答

2

好的,你的问题其实和多进程没有关系。如果你看看你的 data 类的定义(记得类名要首字母大写,这样更符合 Python 的风格),你创建的所有变量都是类变量。你应该把它们放在一个 __init__ 方法里,并且用 self.foo=1 这种方式定义,这样它们就变成实例变量,可以在不同的进程之间传递。像这样:

class Data(object):

    def __init__(self):

        self.SIZE = 8 # dimensions of the game field
        self.MAX_TURNS = 5 # amount of iterations for each of the players ("turns") before the end
        self.turns = 0 # count of turns done
        self.score_PC = self.score_PC2 = 0 # score values

        # create and init the data matrices
        self.data_PC = [['X' for j in xrange(self.SIZE)] for i in xrange(self.SIZE)]
        self.data_PC2 = [['X' for j in xrange(self.SIZE)] for i in xrange(self.SIZE)]

接下来说说多进程的部分。如果你使用的是可加入的队列,实际上不需要加锁。你只需要用 .get() 从队列里取出数据,处理完后再用 .put() 放回队列,并告诉它 .task_done()。这样就能处理好并发的问题。

这里,我发了一个 你代码的修改版本

撰写回答