我有一个有两个线程的应用。一个是运行简单游戏的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线程和:
的情况下运行服务器 try:
while(1):
...
#Receive messages from socket. Add them to pygame event queue
...
except KeyboardInterrupt:
sys.exit(0)
不响应Ctrl + c
pygame窗口标准关闭按钮(小x op右)不再起作用。
我尝试了一种解决方法:
try:
server_thread = ServerThread()
server_thread.start()
pygame_thread = PygameThread()
pygame_thread.start()
except KeyboardInterrupt:
sys.exit(0)
也没有工作。
我正在寻找关闭应用程序的想法,而不必杀死应用程序已经启动的shell。
更新
根据建议我做了以下事情:
将两个踏板中的前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
更新
我做了一个小快捷方式并将服务器线程更改为守护进程,因此一旦pygame窗口(即py pygame线程)关闭,它就会关闭。
答案 0 :(得分:1)
sys.exit
有点令人困惑,因为它实际上并没有终止或“退出”任何东西。它只抛出一个异常,如果你在一个线程中这样做,异常仍然是该线程的本地异常。要在主要环境中抛出SystemExit
,您需要thread.interrupt_main
。
答案 1 :(得分:1)
在主程序的except
- 块中,您应该以某种方式通知您的Thread
自行停止。您可以在this thread查看我的答案,以了解我的意思。
基本上,用while(1):
循环代替while not self.stop_requested:
- 循环。然后,您可以在主线程内设置类的此字段,实际捕获KeyboardInterrupt
。然后你还应该join()
主线程中的每个线程,然后你就安全地知道everthing停止了。
顺便说一句:我根本不会使用while(1)
。 while True
更直观,因为1在循环的每次迭代中被评估为bool
。为什么不写一个预期的bool
?括号也是多余的。这种符号可以追溯到古老的C,它没有布尔类型。