开发者

Issues with data sharing between processes

I'm rather new to Python and I'm working on a multiprocessing example script. The code is ~100 lines long, so you can find it here - http://pastie.org/1813365

It's a simple game that occurs on square fields - they are represented as matrices(list containing x nested lists of x elements each). A separate game field is created for each player.

Each process that I create represents one player. Each turn and for each "player", two coordinates and a digit(0-9) are generated(randomly). Each "player" tries to place its' digit on his coordinates in the field; if there is no digit on another players' field in these coordinates, or the digit is less than the first players' one, or if the first player has the '0'(it is like a 'joker card') - the digit is (well, meant to be) placed on both fields and the player's score is increased. The game ends after a specified number of iterations.

All the data is stored in a single object of the data-containing class that is being transferred from the main thread to the "first player" thread and then is constantly being transferred from one thread to another, back and forth, until the game ends. 'JoinableQueue' is being used for that.

The problem about the code is that it seems that each "player" has its' own copies of both of the game fields. You can see this clearly if you output both game fields from both player each turn - they are identical for each player. For example, the commented line has no effect, since the another player's (that is being printed in his turn) field is never modified:

if x开发者_如何学Go.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

This is especially strange since all the remaining data in the object seem to be working just fine.

What causes such a behavior and how can I fix this?


Ok, your problem doesn't have anything to do with multiprocessing. If you look at your data class definition(you should capitalize your class names, it's pythonic that way), all the variables you are creating are class variables. You want them to be in an __init__ method and defined as self.foo=1 so that they are instance variables and can be passed between the processes. Like so:

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)]

Now a few words about the multiprocessing aspect. You don't really need a lock if you are using the joinable queue. All you need to do is .get() the data, process it and .put() it back in the queue, and let it know that .task_done(). It will take care of the concurrency.

Here, I posted your code with the needed edits.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜