根据源代码,必须从与运行服务器的线程不同的线程调用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上终止进程。
但这显然不是解决这个问题的正确方法。
更新ca. 2013年8月我已经与node.js私奔以满足强大的异步I / O的需求,但是大量的副项目(例如线性代数研究,各种命令行工具前端)让我回到了python。回顾这个问题,BaseHTTPServer可能与其他选项相比没有什么实际价值(比如Phil提到的各种微框架)。
答案 0 :(得分:3)
1。
要创建一个不会永远运行但直到满足某些条件的服务器:
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()
允许一些网址调用将条件设置为终止,使用您喜欢的任何内容。
修改: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可能符合您的需求
答案 1 :(得分:1)
threading.Event对于发信号通知其他线程非常有用。如,
please_die = threading.Event()
# in handler
please_die.set()
# in main thread
please_die.wait()
httpd.shutdown()
如果要在线程之间发送数据,可以使用Queue。