Python SocketServer ThreadingMixIn server_thread 的作用

在 Python SocketServer 的异步(线程)示例中:http://docs.python.org/2/library/socketserver.html 启动了一个服务器线程(称为 server_thread),以便为每个请求启动新的线程。由于捕获 KeyboardInterrupts 出现了一些问题,我开始寻找类似的代码,发现如果不使用 server_thread,实际上 Ctrl-C 会起作用,没有明显区别。尽管我的代码可以正常运行,但我还是想了解:
在这里插入图片描述

  1. 为什么在使用 server_thread 时,一个简单的 try 无法捕获 KeyboardInterrupt?
  2. 示例中的 server_thread 有什么用,与我相对简单的示例相比?

以下是来自 Python SocketServer 示例的代码,其中的 try 无法捕获 KeyboardInterrupt:

if __name__ == "__main__":
    server = ThreadedTCPServer(serverAddr, SomeCode)
    # ...
    # 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()

以下是我的简单示例,其中 Ctrl-C 可以正常工作:

if __name__ == "__main__":
    server = ThreadedTCPServer(serverAddr, SomeCode)
    try:
        server.serve_forever()
        print("Ctrl-C to exit")
    except KeyboardInterrupt:
        print("Interrupt received, exiting")
        server.shutdown()

解决方案

答案 1:

  1. 这是一个普遍的问题。当你按 Ctrl-C 时,一个信号会被发送到进程中。在这个进程中,主线程会捕获信号(如果没有正确处理),主线程就会被打断。但是这个信号并不会杀死其他线程。并且,只要有非守护线程在运行,Python 就会一直运行(因为这并不安全)。如果你知道自己在做什么,可以添加以下代码:
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()

现在应该可以正常工作了(假设你在 server_thread.start() 之后做了一些事情,比如等待,否则 Python 就会退出,不会等待守护线程)。但是请记住,你可能会在某些重要的操作期间杀死你的服务器。为了避免这种情况,你应该实现某种形式的优雅终止:

import signal

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

    # 一些代码
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.start()
    # 一些代码

    try:
        signal.pause()  # 等待信号,可以一个循环?
    except:
        server.shutdown()  # 优雅退出
  1. 它只是在单独的线程中启动了一个服务器。也许这个想法是你可以在此期间执行其他操作?如果你只想运行服务器,就没有必要这样做。
    另外,原因可能是上面提到的那个:优雅退出。如果你只是中断服务器,它就会停止,也许是在某些重要的操作期间。

答案 2:

在 server-thread 示例中,你启动了一个提供内容的新线程。
此线程不是作为守护进程启动的(deamon = False)。这意味着程序在 server_forever() 完成之前不会退出。
因此,主线程什么也不做,程序等待非守护线程关闭。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值