【问题标题】:Close multi threaded application with KeyboardInterrupt使用 KeyboardInterrupt 关闭多线程应用程序
【发布时间】:2013-01-11 08:33:28
【问题描述】:

我有一个有两个线程的应用程序。一个是运行简单游戏的 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)不再起作用。

我尝试的解决方法:

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 窗口(即 pygame 线程)关闭,它就会关闭。

【问题讨论】:

    标签: python multithreading exception exception-handling pygame


    【解决方案1】:

    在您的主程序的except-block 中,您应该以某种方式通知您的Threads 自行停止。您可以在this thread 中查看我的回答,以了解我的意思。

    基本上,将while(1):-loop 替换为while not self.stop_requested:-loop。然后你可以在你的主线程中设置你的类的这个字段,KeyboardInterrupt 实际上是被捕获的。然后你也应该join()你的主线程中的每个线程,然后你就可以安全地知道一切都停止了。

    顺便说一句:我根本不会使用while(1)while True 更直观,因为 1 被评估为 bool 循环的每次迭代。为什么不在预期的地方写bool?括号也是多余的。这种符号可以追溯到古老的 C,它没有布尔类型。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-27
        • 1970-01-01
        • 2017-01-06
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        相关资源
        最近更新 更多