Python SocketServer线程混合服务器线程的用途

Python SocketServer线程混合服务器线程的用途,python,python-2.7,socketserver,Python,Python 2.7,Socketserver,在异步(线程)SocketServer示例中,启动一个服务器线程(称为服务器线程),为每个请求启动新线程。由于一些捕捉键盘中断的问题,我开始寻找类似的代码,发现不使用服务器线程时没有明显的区别,但ctrl-c实际上可以工作 即使我的代码有效,我还是很想知道 1) 在使用服务器线程时,为什么不简单地“尝试”捕捉键盘中断工作 2) 与我比较简单的示例相反,示例中的服务器线程有什么好处 在python SocketServer示例中,在try中捕获键盘中断不起作用: if __name__ == "_

在异步(线程)SocketServer示例中,启动一个服务器线程(称为服务器线程),为每个请求启动新线程。由于一些捕捉键盘中断的问题,我开始寻找类似的代码,发现不使用服务器线程时没有明显的区别,但ctrl-c实际上可以工作

即使我的代码有效,我还是很想知道

1) 在使用服务器线程时,为什么不简单地“尝试”捕捉键盘中断工作

2) 与我比较简单的示例相反,示例中的服务器线程有什么好处

在python SocketServer示例中,在try中捕获键盘中断不起作用:

if __name__ == "__main__":
    server = ThreadedTCPServer(serverAddr, SomeCode)
<snip>
    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.start()
1) 这是一个普遍的问题。当执行CTRL+C时,会向进程发送一个信号。在这个过程中,主线程捕捉到信号,并且(如果处理不当)主线程被中断。但该信号不会杀死其他线程。只要有非守护进程线程在运行,Python就不会退出(因为这样不安全)。如果您知道自己在做什么,可以添加以下内容:

server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
它现在应该可以工作了(假设您在
server\u thread.start()之后做了一些事情,比如等待-否则Python将退出,它不会等待守护进程线程)。但是请记住,在某些重要操作期间,您可能会杀死服务器。为了避免这种情况,您应该实施某种优雅的杀戮:

import signal

if __name__ == "__main__":
    server = ThreadedTCPServer(serverAddr, SomeCode)

    # some code
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.start()
    # some code

    try:
        signal.pause()  # wait for a signal, perhaps in a loop?
    except:
        server.shutdown()  # graceful quit
2) 它只是在一个单独的线程中启动服务器。也许你的想法是你可以同时做其他的手术?如果您只想运行服务器,则无需这样做


还有一个原因可能是我上面提到的:优雅的退出。如果您只是中断服务器,它可能会在某些重要操作期间死掉。

在服务器线程示例中,您启动了一个新线程来提供内容。 此线程不是以deamon(
deamon=False
)启动的。这意味着在完成
服务器\u forever()
之前,程序不会退出。 因此主线程什么也不做,程序等待非deamon线程关闭

  • 我看到的唯一区别是,这个新线程不是主线程,因此不会处理键盘中断或主线程所做的其他事情
  • 如果您想将GUI与服务器集成,这可能很有用。GUI可以并行运行

  • “print”ctrl-c to exit“”仍然会执行,所以我希望这个尝试能够奏效。如果它只是停留在服务器线程中,那么打印不应该工作,或者我错了吗?对不起,你指的是哪种打印?您能解释一下吗?您可以在
    永远服务()
    中中断ThreadedTCServer。这没什么重要的。重要的任务可能在您可能希望等待的处理程序线程中。
    import signal
    
    if __name__ == "__main__":
        server = ThreadedTCPServer(serverAddr, SomeCode)
    
        # some code
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.start()
        # some code
    
        try:
            signal.pause()  # wait for a signal, perhaps in a loop?
        except:
            server.shutdown()  # graceful quit