2009年1月7日水曜日

[Python]multiprocessingを使ったオセロ

Pythonのmultiprocessingを使ってオセロの分散並列処理をやってみました。
サーバのキューに登録されるタスクをクライアントが黙々と計算して結果を返します。

構成はこんな感じです。

  • server.py タスク配布用と結果受け取り用のキューを持っているサーバ。

  • Othello.py オセロの探索を行うクラス。

  • game.py Othelloのサブクラス。オセロの探索対象の局面をサーバのキューに登録するクラス。

  • client.py Othelloのサブクラス。キューに入ったタスクを探索して、評価値を返すクラス。

  • game_launcher.py ユーザからの入力を受け取ってgameに初期条件等を与える。


使い方は

  • サーバでserver.pyを立ち上げる

  • クライアントでclient.pyを立ち上げる

  • クライアントorサーバでgame_launcher.pyを立ち上げる

あとはプロンプトが出てくるので、自分の色を選んで、手を入力して行くと、タスクがクライアントに配布されて探索されます。
クライアントはいくつでも接続できますが、タスク自体が現局面での合法手分しか作られないので、7〜8クライアントぐらいで速度が頭打ちになると思います。

ちょこっと解説。
server.py

task_queue = Queue.Queue()
result_queue = Queue.Queue()
class QueueManager(BaseManager): pass

QueueManager.register('get_task_queue',callable=lambda:task_queue)
QueueManager.register('get_result_queue',callable=lambda:result_queue)
m = QueueManager(address=('',8001),authkey='abc')
s = m.get_server()
s.serve_forever()

タスク配布用と結果受け取り用のキューを作成して、サーバをたてます。
remoteからはサーバに接続した後get_task_queue,get_result_queueでキューを取得できます。

game.py(一部抜粋)

class Game(Othello):

    def __init__(self,color):
        Othello.__init__(self,color)

        QueueManager.register('get_task_queue')
        QueueManager.register('get_result_queue')
        m = QueueManager(address=('example.com',8001),authkey='abc')
        m.connect()
        self.task_queue = m.get_task_queue()
        self.result_queue = m.get_result_queue()

こちらはサーバに接続して、キューを取得しています。
分散並列処理のきもはここだけです。なんて簡単!
あとはタスクをキューに入れて、client側で取って探索するだけ。
client側の接続処理もこの処理と同じです。

0 件のコメント:

コメントを投稿