进程间数据共享问题
我刚接触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 个回答
好的,你的问题其实和多进程没有关系。如果你看看你的 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()
。这样就能处理好并发的问题。
这里,我发了一个 你代码的修改版本。