closing http.server.HTTPServer 保证是线程安全的吗?
Is closing http.server.HTTPServer guaranteed to be thread-safe?
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading
with HTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
threading.Thread(target=httpd.serve_forever, daemon=True).start()
# Do something ...
当程序退出with
块时,是否保证httpd
正常关闭?例如,如果当代码到达 with
块的末尾时 httpd
正在传输数据,该连接是否会被正确切断(或等待直到它完成)?
我的理解是 ThreadingHTTPServer
应该正确处理这些,因为 doc 说:
socketserver.ThreadingMixIn.server_close()
waits until all non-daemon threads complete, except if socketserver.ThreadingMixIn.block_on_close
attribute is false. Use daemonic threads by setting ThreadingMixIn.daemon_threads
to True to not wait until threads complete.
但我想看看 Python 最基本的内置 http 服务器 HTTPServer
是否也能正确处理这个问题。
http.server.HTTPServer
是socketserver.TCPServer
的子类是socketserver.BaseServer
的子类。在BaseServer
中定义了.serve_forever
。此处显示在不同线程中关闭 .serve_forever
的正确方法是调用 .shutdown()
。这是您在 with
语句结束之前应该做的事情。
现在回答您提出的问题:如果您不调用 .shutdown()
,serve_forever
会做什么?好吧,我不确定。 __exit__
函数只关闭套接字,它不做任何清理。答案似乎是 'Whatever your OSes implementation of select.select
does when it has no sockets to select over.' 这是什么?显然,在 Unix 上就像什么都没发生一样继续,在 Windows 上引发异常?这意味着在 Unix 上服务器将永远继续服务,而在 Windows 上它将引发异常。 (请注意,我对此不确定。只是.shutdown()
)
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading
with HTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
threading.Thread(target=httpd.serve_forever, daemon=True).start()
# Do something ...
当程序退出with
块时,是否保证httpd
正常关闭?例如,如果当代码到达 with
块的末尾时 httpd
正在传输数据,该连接是否会被正确切断(或等待直到它完成)?
我的理解是 ThreadingHTTPServer
应该正确处理这些,因为 doc 说:
socketserver.ThreadingMixIn.server_close()
waits until all non-daemon threads complete, except ifsocketserver.ThreadingMixIn.block_on_close
attribute is false. Use daemonic threads by settingThreadingMixIn.daemon_threads
to True to not wait until threads complete.
但我想看看 Python 最基本的内置 http 服务器 HTTPServer
是否也能正确处理这个问题。
http.server.HTTPServer
是socketserver.TCPServer
的子类是socketserver.BaseServer
的子类。在BaseServer
中定义了.serve_forever
。此处显示在不同线程中关闭 .serve_forever
的正确方法是调用 .shutdown()
。这是您在 with
语句结束之前应该做的事情。
现在回答您提出的问题:如果您不调用 .shutdown()
,serve_forever
会做什么?好吧,我不确定。 __exit__
函数只关闭套接字,它不做任何清理。答案似乎是 'Whatever your OSes implementation of select.select
does when it has no sockets to select over.' 这是什么?显然,在 Unix 上就像什么都没发生一样继续,在 Windows 上引发异常?这意味着在 Unix 上服务器将永远继续服务,而在 Windows 上它将引发异常。 (请注意,我对此不确定。只是.shutdown()
)