2

根据来源,必须从与服务器运行的线程不同的线程调用 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 提到的各种微框架)相比,可能没有什么实用价值。

4

2 回答 2

3

1.来自BaseHTTPServer 文档

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

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 通常比你想去的低。有很多微框架可能适合您的需求

于 2012-07-15T17:41:12.157 回答
2

threading.Event对于向其他线程发出信号很有用。例如,

please_die = threading.Event()

# in handler
please_die.set()

# in main thread
please_die.wait()
httpd.shutdown()

如果要在线程之间发送数据,可以使用队列。

于 2012-07-15T17:44:41.153 回答