【问题标题】:Python BaseHTTPServer: How to get it to stop?Python BaseHTTPServer:如何让它停止?
【发布时间】:2012-07-14 16:35:31
【问题描述】:

根据源代码,BaseServer.shutdown() 必须从与运行服务器的线程不同的线程调用。

但是,我正在尝试使用在 Web 请求中提供给服务器的特定值来关闭服务器。

请求处理程序显然是在这个线程中运行的,所以在我这样做之后它仍然会死锁:

httpd = BaseHTTPServer.HTTPServer(('', 80), MyHandler)
print("Starting server in thread")
threading.Thread(target=httpd.serve_forever).start()

我怎样才能完成我想要的?我必须设置一个套接字或管道或其他东西(请告诉我如何做到这一点,如果它是解决方案),主线程可以阻塞并等待子线程发送消息,此时它将能够调用shutdown()?

我目前能够通过从请求处理程序调用“httpd.socket.close()”来实现某种“工作”行为。这会产生一个[Errno 9] Bad file descriptor 错误,并且似乎终止了 Windows 上的进程。

但这显然不是解决此问题的正确方法。

大约更新。 2013 年 8 月 我已经与 node.js 私奔来满足强大的异步 I/O 的需求,但是大量的副项目(例如线性代数研究、各种命令行工具前端)让我回到了 python。回过头来看这个问题,BaseHTTPServer 与其他选项(如 Phil 提到的各种微框架)相比,可能没有什么实用价值。

【问题讨论】:

    标签: python windows sockets


    【解决方案1】:

    1.来自BaseHTTPServer docs

    创建一个不会永远运行但直到满足某些条件的服务器:

    def run_while_true(server_class=BaseHTTPServer.HTTPServer,
                       handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
        """
        This assumes that keep_running() is a function of no arguments which
        is tested initially and after each request.  If its return value
        is true, the server continues.
        """
        server_address = ('', 8000)
        httpd = server_class(server_address, handler_class)
        while keep_running():
            httpd.handle_request()
    

    允许一些 url 调用来设置终止条件,在那里使用任何你喜欢的东西。

    编辑keep_running 是您选择的任何函数,可以很简单:

    def keep_running():
        global some_global_var_that_my_request_controller_will_set
        return some_global_var_that_my_request_controller_will_set 
    

    你可能想要更聪明的东西和without_rediculously_long_var_names

    2. BaseHTTPServer 通常比你想去的要低。有plenty of micro-frameworks 可能适合您的需求

    【讨论】:

    • 这里没有指定keep_running()是什么。
    • @StevenLu 不,这是你的功能,所以你想要什么。 (见编辑)
    • 这不是一个会吞噬整个核心的繁忙循环吗? ಠ_ಠ 或者,handle_request() 是否足够聪明,可以执行 0.5 秒 select 循环?
    • @StevenLu No. handle_request 调用 select.select 将等待 fd(在这种情况下为套接字)准备好进行 IO。它尊重超时,serve_forever 进行了相同的调用,不会占用 CPU。
    【解决方案2】:

    threading.Event 可用于向其他线程发送信号。例如,

    please_die = threading.Event()
    
    # in handler
    please_die.set()
    
    # in main thread
    please_die.wait()
    httpd.shutdown()
    

    如果你想在线程之间发送数据,你可以使用Queue

    【讨论】:

      猜你喜欢
      • 2011-03-05
      • 2013-09-08
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多