如何可靠地知道单独线程中的 HTTPServer 已启动并提供服务?
How to reliably know that HTTPServer in a separate thread is up and serving?
我正在新线程中启动一个 HTTPServer
对象:
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading
with HTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()
# Doing my work ...
httpd.shutdown()
在这里,我想确保在达到# doing my work...
之前httpd.serve_forever()
已经成功启动。我当然可以在 thread.start()
之后插入 thread.join(timeout=1)
,但这仍然存在竞争条件的风险。有没有一种可靠的方法可以等到 serve_forever
启动并且 运行?
没问题。有一个 callback called service_actions
在 serve_forever
循环的每次迭代后调用,您可以在其中使用 threading.Event()
等待。
由于在每个可能服务的请求之后调用回调,它会导致最多 0.5 秒的初始延迟(默认情况下),但我不认为这是一个问题。如果是,您可以覆盖 serve_forever
以在第一个请求服务之前执行此操作。
import threading
from http.server import HTTPServer, SimpleHTTPRequestHandler
class SignalingHTTPServer(HTTPServer):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.ready_event = threading.Event()
def service_actions(self):
self.ready_event.set()
with SignalingHTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()
httpd.ready_event.wait()
# Doing my work ...
httpd.shutdown()
我正在新线程中启动一个 HTTPServer
对象:
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading
with HTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()
# Doing my work ...
httpd.shutdown()
在这里,我想确保在达到# doing my work...
之前httpd.serve_forever()
已经成功启动。我当然可以在 thread.start()
之后插入 thread.join(timeout=1)
,但这仍然存在竞争条件的风险。有没有一种可靠的方法可以等到 serve_forever
启动并且 运行?
没问题。有一个 callback called service_actions
在 serve_forever
循环的每次迭代后调用,您可以在其中使用 threading.Event()
等待。
由于在每个可能服务的请求之后调用回调,它会导致最多 0.5 秒的初始延迟(默认情况下),但我不认为这是一个问题。如果是,您可以覆盖 serve_forever
以在第一个请求服务之前执行此操作。
import threading
from http.server import HTTPServer, SimpleHTTPRequestHandler
class SignalingHTTPServer(HTTPServer):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.ready_event = threading.Event()
def service_actions(self):
self.ready_event.set()
with SignalingHTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()
httpd.ready_event.wait()
# Doing my work ...
httpd.shutdown()