我正在为C / C ++ HTTP / HTTPS客户端整理测试工具,我想在测试工具中使用python作为服务器。 Python似乎有一组非常好的TCP / HTTP服务器和处理程序类,看起来它将成为完成此任务的阻力最小的路径。
那就是说,我试图弄清楚如何优雅地关闭TCPServer
对象。我的测试工具是用C ++编写的,我想使用popen()
来调用服务器,因为它不像system()
那样有问题,而且它在我所有的目标平台上都可用(Windows,OSX,Linux)。鉴于我使用popen()
来启动python服务器,我不会让python进程的PID可用,所以我不能轻易{{1} } 服务器。
我以为我想发送一个' q'服务器进程的STDIN字符,或者将STDIN管道关闭到服务器,发送EOF以使其正常关闭。我无法找到一个非常棒的方法。
当您调用SIGTERM
方法时, TCPServer
/ HTTPServer
/等开始工作。因此,当我在其上调用一个名为.serve_forever()
的方法时,我不应该感到惊讶,TCPServer
很难让.serve_forever()
永远停止服务。作为替代方案,BaseHTTPServer
的python文档建议反复调用.handle_request()
:
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()
但是,它也不能很好地工作 - 它依赖于服务器接收并完成检查是否继续运行的请求 - 如果服务器没有得到请求,它不会#39; t从.handle_request()
返回。
TCPServer
有一个名为.shutdown()
的方法:
BaseServer.shutdown()
Tell the serve_forever() loop to stop and wait until it does.
New in version 2.6.
这是线程安全的吗?我知道GIL,但我仍然想知道这是否被认为是正确的事情,考虑到像PyPy这样的替代python实现。我可以在另一个线程上等待STDIN,然后在STDIN上获得EOF时安全地调用TCPServer
的{{1}}方法吗?
答案 0 :(得分:1)
是的,BaseServer.shutdown()
方法是线程安全的。
serve_forever
方法一直有效,直到设置了shutdown标志,并且设置该标志是shutdown()
的任务。该方法在docstring:
阻止循环结束。必须在此时调用 serve_forever()在另一个线程中运行,否则会死锁。
请注意,这与GIL无关;这只限制了Python进程可以有效利用C扩展和I / O之外的多少核心。