我有一个有两个线程的应用程序。一个是运行一个简单游戏的pygame线程,另一个线程是一个监听服务器,它接收用于控制游戏的消息。在
下面是精简的伪代码:
class ServerThread(threading.Thread):
def run(self):
class SingleTCPHandler(SocketServer.BaseRequestHandler):
try:
while(1):
...
#Receive messages from socket. Add them to pygame event queue
...
except keyboardInterrupt:
sys.exit(0)
...
...
class PygameThread(threading.Thread):
def run(self):
...
#pygame stuff
...
#The following pygame code closed the app when closing the pygame window while running as a single thread
for event in pygame.event.get():
if event.type==QUIT:
exit()
...
try:
server_thread = ServerThread()
server_thread.start()
pygame_thread = PygameThread()
pygame_thread.start()
except KeyboardInterrupt:
sys.exit(0)
似乎没有一个例外被发现。我尝试过只运行服务器而不使用pygame线程和:
^{pr2}$不响应Ctrl + c
pygame窗口的标准关闭按钮(右上方的小x)不再工作。在
我尝试了一种变通方法:
try:
server_thread = ServerThread()
server_thread.start()
pygame_thread = PygameThread()
pygame_thread.start()
except KeyboardInterrupt:
sys.exit(0)
也不管用。在
我正在寻找的想法,以关闭应用程序,而不必杀死的外壳,该应用程序已启动。在
更新
基于这个建议,我做了以下几点:
将两个踏板中的前一个while True
更改为while not self.stop_requested:
。在
还有:
try:
pygame_thread = PygameThread()
pygame_thread.start()
server_thread = ServerThread()
server_thread.start()
except KeyboardInterrupt:
pygame_thread.stop_requested = True
server_thread.stop_requested = True
它仍然不起作用。我还注意到在控制台中,当我试图用Ctrl+c终止时,它只会被打印出来。在
alan@alan ~/.../py $ python main.py
^C^C^C^C^C^C^C
更新
我做了一个小的快捷方式,并将服务器线程改为daemon,因此一旦pygame窗口(即pygame线程)关闭,它就会关闭。在
sys.exit
是一个令人困惑的名称,因为它实际上并不终止或“退出”任何内容。它只抛出一个异常,如果你在一个线程中这样做,这个异常仍然是该线程的本地异常。要在主上下文中抛出SystemExit
,您需要^{在主程序的
except
-块中,您应该以某种方式通知您的Thread
自行停止。你可以看看我在this thread里的答案,了解我的意思。在基本上,将
while(1):
-循环替换为while not self.stop_requested:
-循环。然后,您可以从主线程内部设置类的这个字段,在这里KeyboardInterrupt
实际上被捕捉到。然后,您还应该join()
从主线程开始的每个线程,然后您就可以安全地知道所有的线程都停止了。在顺便说一句:我根本不会用
while(1)
。while True
更直观,因为1在循环的每次迭代中都被计算为bool
。为什么不在预期的地方写一个bool
?括号也是多余的。这种表示法可以追溯到旧的C语言,它没有布尔类型。在相关问题 更多 >
编程相关推荐