为什么 PyGame 与 PyMongo 结合使用时会冻结?
Why does PyGame freeze when used in combination with PyMongo?
这是什么错误,我不知道该怎么办...(PyMongo)。
Traceback (most recent call last):
File "C:/Users/aatif/Documents/Projects/Games with pygame/Space Invader/Game with DB.py", line 248, in <module>
play()
File "C:/Users/aatif/Documents/Projects/Games with pygame/Space Invader/Game with DB.py", line 23, in play
c.insert_one({'Score': 3})
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py", line 698, in insert_one
self._insert(document,
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py", line 613, in _insert
return self._insert_one(
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py", line 602, in _insert_one
self.__database.client._retryable_write(
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1497, in _retryable_write
with self._tmp_session(session) as s:
File "C:\Users\aatif\AppData\Local\Programs\Python\Python38-32\lib\contextlib.py", line 113, in __enter__
return next(self.gen)
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1829, in _tmp_session
s = self._ensure_session(session)
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1816, in _ensure_session
return self.__start_session(True, causal_consistency=False)
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1766, in __start_session
server_session = self._get_server_session()
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1802, in _get_server_session
return self._topology.get_server_session()
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\topology.py", line 490, in get_server_session
self._select_servers_loop(
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\topology.py", line 215, in _select_servers_loop
raise ServerSelectionTimeoutError(
pymongo.errors.ServerSelectionTimeoutError: connection closed,connection closed,connection closed, Timeout: 30s, Topology Description: <TopologyDescription id: 600999bd9735fa26e13f796f, topology_type: ReplicaSetNoPrimary, servers: [<ServerDescription ('firstproject-shard-00-00.wy4pd.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('connection closed')>, <ServerDescription ('firstproject-shard-00-01.wy4pd.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('connection closed')>, <ServerDescription ('firstproject-shard-00-02.wy4pd.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('connection closed')>]>
是我的服务器离线了还是我设置有误?
这是一个示例(非常短但出现同样的问题)
import pygame
from pymongo import MongoClient
# Eisa -> Username, LolLol65 -> Password
pygame.init()
win = pygame.display.set_mode((1000, 400))
run = True
cluster = MongoClient(
'mongodb+srv://USER:PASSWORD@firstproject.wy4pd.mongodb.net/Calculator?retryWrites=true&w=majority')
db = cluster['Game']
c = db['Scores']
score = 0
while run:
score += 1
win.fill((0, 0, 0))
for e in pygame.event.get():
if e.type == pygame.QUIT:
run = False
if e.type == pygame.KEYDOWN:
c.insert_one({'Score': score})
pygame.display.update()
(由于评论要求我添加代码。这段代码重现了同样的问题,但如果更好的话我也可以添加完整代码)
您遇到的具体异常似乎与您的 mongo 连接有关。您可以连接到 MongDB Compass 中的数据库吗?
无论如何,您当前的架构将使您的游戏循环依赖于数据库写入,这可能会花费大量时间。
我创建了一个示例,它使用单独的线程来管理 MongoDB 连接并使用 queue 与主线程通信。此示例还包括标题栏中的帧速率,并将游戏循环限制为 60 FPS。如果将其添加到现有脚本中,只要发生数据库插入,您应该会看到帧速率下降。
import time
import threading
import queue
import pygame
import pymongo
# Thread for Database storage
class MongoThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
self.daemon = True
def run(self):
t_running = True
client = pymongo.MongoClient("mongodb+srv://<insert-your-connection-string-here>")
db = client.test
c = db.scores
while t_running:
if self.queue.empty():
time.sleep(0.1)
pass
else:
data = self.queue.get()
if data == "exit":
t_running = False
else:
# do something with the queud data
c.insert_one(data)
print(c.count_documents({})) # for debugging
WIDTH, HEIGHT = 1000, 400
FPS = 60
# create a queue to send commands from the main thread
q = queue.Queue()
# create and then start the thread
mongo_thread = MongoThread(q)
mongo_thread.start()
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
run = True
score = 0
while run:
for e in pygame.event.get():
if e.type == pygame.QUIT:
run = False
q.put("exit")
if e.type == pygame.KEYDOWN:
# c.insert_one({"Score": score})
q.put({"Score": score})
score += 1
win.fill((0, 0, 0))
pygame.display.update()
pygame.display.set_caption(f"FPS: {clock.get_fps():.1f}")
clock.tick(FPS)
pygame.quit()
这是什么错误,我不知道该怎么办...(PyMongo)。
Traceback (most recent call last):
File "C:/Users/aatif/Documents/Projects/Games with pygame/Space Invader/Game with DB.py", line 248, in <module>
play()
File "C:/Users/aatif/Documents/Projects/Games with pygame/Space Invader/Game with DB.py", line 23, in play
c.insert_one({'Score': 3})
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py", line 698, in insert_one
self._insert(document,
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py", line 613, in _insert
return self._insert_one(
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\collection.py", line 602, in _insert_one
self.__database.client._retryable_write(
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1497, in _retryable_write
with self._tmp_session(session) as s:
File "C:\Users\aatif\AppData\Local\Programs\Python\Python38-32\lib\contextlib.py", line 113, in __enter__
return next(self.gen)
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1829, in _tmp_session
s = self._ensure_session(session)
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1816, in _ensure_session
return self.__start_session(True, causal_consistency=False)
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1766, in __start_session
server_session = self._get_server_session()
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\mongo_client.py", line 1802, in _get_server_session
return self._topology.get_server_session()
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\topology.py", line 490, in get_server_session
self._select_servers_loop(
File "C:\Users\aatif\PycharmProjects\pythonProject6\venv\lib\site-packages\pymongo\topology.py", line 215, in _select_servers_loop
raise ServerSelectionTimeoutError(
pymongo.errors.ServerSelectionTimeoutError: connection closed,connection closed,connection closed, Timeout: 30s, Topology Description: <TopologyDescription id: 600999bd9735fa26e13f796f, topology_type: ReplicaSetNoPrimary, servers: [<ServerDescription ('firstproject-shard-00-00.wy4pd.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('connection closed')>, <ServerDescription ('firstproject-shard-00-01.wy4pd.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('connection closed')>, <ServerDescription ('firstproject-shard-00-02.wy4pd.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('connection closed')>]>
是我的服务器离线了还是我设置有误? 这是一个示例(非常短但出现同样的问题)
import pygame
from pymongo import MongoClient
# Eisa -> Username, LolLol65 -> Password
pygame.init()
win = pygame.display.set_mode((1000, 400))
run = True
cluster = MongoClient(
'mongodb+srv://USER:PASSWORD@firstproject.wy4pd.mongodb.net/Calculator?retryWrites=true&w=majority')
db = cluster['Game']
c = db['Scores']
score = 0
while run:
score += 1
win.fill((0, 0, 0))
for e in pygame.event.get():
if e.type == pygame.QUIT:
run = False
if e.type == pygame.KEYDOWN:
c.insert_one({'Score': score})
pygame.display.update()
(由于评论要求我添加代码。这段代码重现了同样的问题,但如果更好的话我也可以添加完整代码)
您遇到的具体异常似乎与您的 mongo 连接有关。您可以连接到 MongDB Compass 中的数据库吗?
无论如何,您当前的架构将使您的游戏循环依赖于数据库写入,这可能会花费大量时间。
我创建了一个示例,它使用单独的线程来管理 MongoDB 连接并使用 queue 与主线程通信。此示例还包括标题栏中的帧速率,并将游戏循环限制为 60 FPS。如果将其添加到现有脚本中,只要发生数据库插入,您应该会看到帧速率下降。
import time
import threading
import queue
import pygame
import pymongo
# Thread for Database storage
class MongoThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
self.daemon = True
def run(self):
t_running = True
client = pymongo.MongoClient("mongodb+srv://<insert-your-connection-string-here>")
db = client.test
c = db.scores
while t_running:
if self.queue.empty():
time.sleep(0.1)
pass
else:
data = self.queue.get()
if data == "exit":
t_running = False
else:
# do something with the queud data
c.insert_one(data)
print(c.count_documents({})) # for debugging
WIDTH, HEIGHT = 1000, 400
FPS = 60
# create a queue to send commands from the main thread
q = queue.Queue()
# create and then start the thread
mongo_thread = MongoThread(q)
mongo_thread.start()
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
run = True
score = 0
while run:
for e in pygame.event.get():
if e.type == pygame.QUIT:
run = False
q.put("exit")
if e.type == pygame.KEYDOWN:
# c.insert_one({"Score": score})
q.put({"Score": score})
score += 1
win.fill((0, 0, 0))
pygame.display.update()
pygame.display.set_caption(f"FPS: {clock.get_fps():.1f}")
clock.tick(FPS)
pygame.quit()