2

Python2.7用の新しいMinecraftPiEditionAPIを使用してゲームを作成しようとしています。コードの2つのセクションが互いにブロックしていることに気付いたとき、ゲームはほぼ終了しました。セクションAを最初に配置すると、セクションAが終了するまで、セクションBが実行されなくなります。セクションBを最初に配置すると、実行速度が非常に遅くなります。2つのセクションを2つの別々のスレッドに分割する必要があると判断しました。'

これは、まだ問題が発生しているコードの縮小版です。ClassName.start()2つのクラスの一方の行をコメントアウトすると、もう一方のクラスはエラーなしで実行されることに気付きました。

import mcpi.minecraft as minecraft
import threading

mc = minecraft.Minecraft.create()

class BlockCheckThread(threading.Thread):
    def run(self):
        while True:
            event = mc.events.pollBlockHits()

class WinningCheckThread(threading.Thread):
    def run(self):
        while True:
            blockTest = mc.getBlock(1, 1, 1,) == 50

def main():
    WinningCheckThread().start() # If I comment out either of these .start() lines
    BlockCheckThread().start()   # the other class executes perfectly.

これを実行したことによるエラーは次のとおりです。

Exception in thread Thread-2:
...
TypeError: Hit() takes exactly 5 arguments (1 given)

Exception in thread Thread-1:
...
ValueError: invalid literal for int() with base 10: '

コードを実行するには、Raspberry Piが必要であり、ここapi/python/からMinecraftをダウンロードする必要があります。次に、ディレクトリから実行する必要があります。mcpi(つまり、インポートするモジュールと同じフォルダーにある必要があります。)

これは私の最初のスレッド化の試みなので、私のコードをあまり笑わないでください。このコードが機能しない理由と、それを修正するために何をすべきかを知りたいです。

4

2 に答える 2

4

オブジェクトを共有していますがMinecraft、スレッドセーフではありません。オブジェクトは、コマンドで開始されたMinecraftサーバーに接続するためのMinecraft単なるクライアントライブラリminecraft-piです。スレッドごとにオブジェクトを作成する必要があり、Minecraftそれで問題ないはずです。

import mcpi.minecraft as minecraft
import threading

class BlockCheckThread(threading.Thread):
    def run(self):
        mc = minecraft.Minecraft.create()
        while True:
            event = mc.events.pollBlockHits()

class WinningCheckThread(threading.Thread):
    def run(self):
        mc = minecraft.Minecraft.create()
        while True:
            blockTest = mc.getBlock(1, 1, 1,) == 50

def main():
    WinningCheckThread().start() 
    BlockCheckThread().start()   
于 2013-02-12T15:23:04.860 に答える
3

PiEditionのPythonMinecraftクライアントはスレッドセーフではありません。何が起こるかというと、2つのスレッドが同時にデータを送信および受信します。応答が混同されると(つまり、BlockCheckThreadの要求に対する応答を取得する場合、WinningCheckThreadまたはその逆の場合)、メッセージ形式はスレッドが取得することを期待するものと一致しません。

Minecraftクライアントの各呼び出しをロックするだけで、一度に1つのアイテムのみを送受信できるようになります。

Minecraftサーバーがサポートしているかどうかはわかりませんが、複数のリクエストを送信できる場合もあります。そのためには、未処理のリクエストの順序を追跡するマネージャークラスが必要です。

于 2013-02-12T15:11:57.420 に答える