2013-01-11 41 views
2

我有两个线程的应用程序。一个是运行简单游戏的pygame线程,另一个线程是一个监听服务器,它接受用于控制游戏的消息。用KeyboardInterrupt关闭多线程应用程序

这里是精简伪代码:

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运权)不工作了。

我的解决方法的尝试:

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终止时,在运行此代码的控制台中,它只被打印出来。

[email protected] ~/.../py $ python main.py 
^C^C^C^C^C^C^C 

更新

我做了一些快捷方式,并改变了服务器线程后台程序,所以它关闭,一旦pygame的窗口(这是THA pygame的线程)被关闭。

回答

1

在你的主程序的except区块中,你应该以某种方式通知你的Thread停止它们自己。你可以在this thread看我的答案,以了解我的意思。

基本上,用while not self.stop_requested: -loop替代while(1): -loop。然后,您可以从主线程中设置您的班级的这个字段,其中KeyboardInterrupt实际上被捕获。然后你也应该从你的主线程中获得每个线程的join(),然后你就可以安全地知道停止了。我不会使用while(1)while True更直观,因为1被评估为每循环迭代bool。为什么不写一个bool预期的地方?括号也是多余的。这种符号可以追溯到古老的C,它没有布尔类型。

1

sys.exit有点令人困惑的名字,因为它并没有真正终止或“退出”任何东西。它只会抛出一个异常,并且如果你在一个线程中这样做,该异常仍然是该线程本地的。要在主环境中抛出SystemExit,您将需要thread.interrupt_main