我是Python的新手,我正在研究一个多处理示例脚本。代码长约100行,因此您可以在此处找到它 - http://pastie.org/1813365
这是一个简单的游戏,发生在方形字段上 - 它们表示为矩阵(列表包含每个x元素的x个嵌套列表)。为每个玩家创建单独的游戏区域。
我创建的每个进程代表一个玩家。每个转弯和每个“玩家”,生成两个坐标和一个数字(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
这一点特别奇怪,因为对象中的所有剩余数据似乎都运行得很好。
导致此类行为的原因以及如何解决此问题?
答案 0 :(得分:2)
好的,您的问题与多处理没有任何关系。如果你看一下你的data
类定义(你应该把你的类名大写,那就是 pythonic ),你创建的所有变量都是类变量。您希望它们位于__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()
。它会照顾并发性。
在这里,我发布了your code with the needed edits。