停止BaseHTTPServer使用ThreadingMixin生成的线程

2024-05-14 06:56:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我在this post上读到,使用ThreadingMixin(来自SocketServer模块),您可以使用BaseHTTPServer创建一个线程服务器。我试过了,它确实有效。但是,如何停止服务器产生的活动线程(例如,在服务器关闭期间)?这可能吗?在


Tags: 模块服务器thispost线程basehttpserversocketserverthreadingmixin
2条回答

下面是示例代码,演示如何使用线程。事件要在任何POST请求时关闭服务器

import SocketServer
import BaseHTTPServer
import threading

quit_event = threading.Event()

class MyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  """This handler fires the quit event on POST."""
  def do_GET(self):
    self.send_response(200)
  def do_POST(self):
    quit_event.set()
    self.send_response(200)


class MyThreadingHTTPServer(
    SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
  pass

server = MyThreadingHTTPServer(('', 8080), MyRequestHandler)
threading.Thread(target=server.serve_forever).start()
quit_event.wait()
server.shutdown()

服务器已完全关闭,因此您可以立即重新启动服务器,并且端口可用,而不是获取“地址已在使用中”。在

最简单的解决方案是使用daemon_threads。简短的版本是:只需将此设置为True,不必担心;当您退出时,任何仍在工作的线程都将自动停止。在

正如^{} docs所说:

When inheriting from ThreadingMixIn for threaded connection behavior, you should explicitly declare how you want your threads to behave on an abrupt shutdown. The ThreadingMixIn class defines an attribute daemon_threads, which indicates whether or not the server should wait for thread termination. You should set the flag explicitly if you would like threads to behave autonomously; the default is False, meaning that Python will not exit until all threads created by ThreadingMixIn have exited.

更多详细信息请参见^{} docs

A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property.

有时这样做是不合适的,因为您希望不退出就关闭,或者您的处理程序可能需要进行清理。但当它是适当的,你就再也不会简单了。在

如果您只需要一种不退出就关机的方法,并且不需要保证清理,那么您可以通过ctypeswin32api来使用特定于平台的线程取消api。这通常是一个坏主意,但有时它是你想要的。在

如果你需要干净的关闭,你需要建立你自己的机器,在那里线程合作。例如,您可以创建一个受^{}保护的全局“quit flag”变量,并让您的handle函数定期对此进行检查。在

如果线程执行的是缓慢的、非阻塞的工作,那么这是非常好的,您可以将其分解成更小的块。例如,如果handle函数总是至少每5秒钟检查一次quit标志,则可以保证能够在5秒内关闭线程。但是,如果线程正在按其可能的方式执行阻塞工作,因为使用ThreadingMixIn的全部原因是允许您进行阻塞调用,而不是编写select循环或使用{}或类似的方法?在

好吧,没有好的答案。显然,如果您只需要“最终”而不是“5秒钟内”关闭(或者如果您愿意在5秒钟后放弃干净的关闭,转而使用特定于平台的API或对线程进行守护),那么您只需在每次阻塞调用之前和之后进行检查,它将“经常”起作用。但如果这还不够好,你真的无能为力。在

如果您需要这样做,最好的答案是改变您的体系结构,使用一个有办法做到这一点的框架。最流行的选择是^{}^{},和{a6}。将来,PEP 3156将在标准库中引入类似的功能,如果您不想为现实世界构建一些必须很快准备好的东西,那么有一个部分完整的引用实现^{}值得一试。在

相关问题 更多 >

    热门问题