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 需要在线程之间移动,如果线程处于 I/O 等待状态,则等待 GIL 设置的操作数继续包含在内. 如果你想使用线程,你应该了解它在 Python 中是如何工作的,并阅读有关 GIL 在 python3 中的改进以管理线程滞后问题。对于您的问题,您应该设置一个套接字并准备线程以仅接收数据。

您有一个很棒的关于套接字的教程和一个易于检查的二元潮线程示例

希望有帮助

于 2013-03-05T15:46:43.297 回答