我已在this post上阅读了ThreadingMixin
(来自SocketServer
模块),您可以使用BaseHTTPServer
创建一个线程服务器。我试过了, 工作了。但是,如何停止服务器生成的活动线程(例如,在服务器关闭期间)?这可能吗?
答案 0 :(得分:7)
最简单的解决方案是使用daemon_threads
。简短的版本是:只需将其设置为True,不要担心;当你退出时,任何仍在工作的线程都会自动停止。
正如ThreadingMixIn
docs所说:
中提供了更多详细信息当从ThreadingMixIn继承线程连接行为时,您应该明确声明线程在突然关闭时的行为方式。 ThreadingMixIn类定义了一个属性daemon_threads,它指示服务器是否应该等待线程终止。如果您希望线程自动运行,则应该显式设置标志;默认值为False,这意味着在ThreadingMixIn创建的所有线程都退出之前,Python不会退出。
线程可以标记为“守护程序线程”。这个标志的意义在于,当只剩下守护进程线程时,整个Python程序都会退出。初始值继承自创建线程。可以通过守护程序属性设置标志。
有时这是不合适的,因为您希望在不退出的情况下关闭,或者因为您的处理程序可能需要进行清理。但是当 合适时,你就不会变得更简单了。
如果你需要的只是一种在不退出的情况下关闭的方法,并且不需要保证清理,你可以通过ctypes
或win32api
使用特定于平台的线程消除API。这通常是一个坏主意,但偶尔也是你想要的。
如果您需要干净关闭,您需要为线程配合构建自己的机器。例如,您可以创建一个受threading.Condition
保护的全局“退出标记”变量,并让您的handle
函数定期检查。
如果线程正在执行缓慢,无阻塞的工作,您可以分解成更小的部分,这是非常好的。例如,如果handle
函数始终每5秒至少检查一次退出标志,则可以保证能够在5秒内关闭线程。但是如果线程正在进行阻塞工作会怎么样 - 因为你使用ThreadingMixIn
的原因是让你进行阻塞调用而不是编写select
循环或使用asyncore
或之类的?
嗯,没有好的答案。显然,如果您只需要“最终”而不是“在5秒内”发生关闭(或者如果您愿意在5秒后放弃干净关闭,并恢复使用特定于平台的API或守护线程),那么可以在每次阻塞调用之前和之后放置检查,它将“经常”工作。但如果这还不够好,你真的无能为力。
如果您需要,最好的答案是更改您的架构以使用具有此方法的框架。最受欢迎的选择是Twisted
,Tornado
和gevent
。将来,PEP 3156会在标准库中引入类似的功能,并且如果你没有尝试为现实世界构建一些东西,那么值得玩的是部分完整的参考实现tulip
准备好了。
答案 1 :(得分:0)
以下示例代码显示如何使用threading.Event在任何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()
服务器干净地关闭,因此您可以立即重新启动服务器并且端口可用,而不是获取“已在使用的地址”。