2

私はPythonに比較的慣れていないので、かなり長い間この問題に悩まされてきました。

基本的に、私が作成しているモジュールはゲーム内で使用されます(モジュールpygameを使用)が、Pygameモジュールを使用してキーボードから押されたキーを受信する代わりに、UDP経由で送信されるネットワークを介してこれらのキーを受信したいと思います。

別のスレッドで定義されたUDPポートをリッスンし、呼び出される必要がある場所でゲーム内で使用するために押されたキーを返すモジュールを作成しました。

私が書いたコードはしばらくは機能しますが、非常に遅くなり、しばらくすると次のエラーメッセージが表示されます。

Traceback (most recent call last):
  File "game.py", line 164, in <module>
  File "/usr/lib/python2.7/dist-packages/pygame/sprite.py", line 399, in update
  File "/home/globe/Desktop/Asteroids/sprites.py", line 41, in update
  File "/home/globe/Desktop/Asteroids/networkControlLatest.py", line 18, in getKeyPressed
  File "/home/globe/Desktop/Asteroids/networkControlLatest.py", line 8, in __init__
  File "/usr/lib/python2.7/socket.py", line 187, in __init__
socket.error: [Errno 24] Too many open files
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 66, in apport_excepthook
ImportError: No module named fileutils

Original exception was:
Traceback (most recent call last):
  File "game.py", line 164, in <module>
  File "/usr/lib/python2.7/dist-packages/pygame/sprite.py", line 399, in update
  File "/home/globe/Desktop/Asteroids/sprites.py", line 41, in update
  File "/home/globe/Desktop/Asteroids/networkControlLatest.py", line 18, in getKeyPressed
  File "/home/globe/Desktop/Asteroids/networkControlLatest.py", line 8, in __init__
  File "/usr/lib/python2.7/socket.py", line 187, in __init__
socket.error: [Errno 24] Too many open files

networkControlLatest.pyファイルは次のとおりです。

*****from socket import *
import threading
#Class to get key pressed UDP packet on a separate thread
class networkReceive(threading.Thread):
     def __init__(self,address):
         threading.Thread.__init__(self)
     self.address = address
     self.server_socket = socket(AF_INET, SOCK_DGRAM)
         self.server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
     self.server_socket.bind(self.address)
         self.recv_data = ''

     def run(self):
         self.recv_data, addr = self.server_socket.recvfrom(2048)

def getKeyPressed():
    address = ('129.11.148.65', 6005)
    thread = networkReceive(address)
    thread.start()
    thread.join(0.01)
        recv_data = thread.recv_data
    thread.server_socket.close()
    print recv_data
    return recv_data*****

game.pyファイル内でこれが呼び出される例は次のとおりです。

keys = networkControlLatest.getKeyPressed()
        if keys == 'A':
            laser = sprites.Bullet(screen,Ship.angle,Ship.rect.center)
            bulletgroup.add (pygame.sprite.Group(laser))
            delay = 15 

ゲームはキーボードを使用して正常に動作するので、ネットワークの側面に問題があることはわかっています。私は一生の間、それが何であるかを正確に理解することはできません。どんな助けでも大歓迎です、私はこのコードをずっとずっと見つめていました..!

4

1 に答える 1

4

キーを押すたびに新しいソケットを使用し、スレッドを実行してデータを取得します。スレッドでソケットを生成し、データをキューに書き込み、キューから getkeyPresed() を読み込みます。

私の2セント。

編集: @cfi が言ったように、あなたの問題は主に、呼び出しごとにソケットを閉じて新しいソケットを開始しないことです。何度かキーを押した後、システムで利用可能なファイル記述子が限界に達し、Python の GIL がスレッドからスレッドに移動し、GIL によって設定された数の ops を待機して、スレッドが I/O 待機中の場合に包括的に続行する必要があります。 . スレッドを使用する場合は、Python でスレッドがどのように機能するかを理解し、スレッド ラグの問題を管理するために python3 での GIL の改善について読む必要があります。あなたの問題については、ソケットをセットアップし、データのみを受信するようにスレッドを準備する必要があります。

ソケットに関する優れたチュートリアルと、バイナリタイドでのスレッドの簡単な確認例があります

それが役立つことを願っています

于 2013-03-05T15:46:43.297 に答える