我遇到一个奇怪的问题,即如果在请求处理程序中,subprocess.Popen会生成一个新进程,则会阻止SimpleHTTPRequestHandler中的请求返回。但Popen不应该异步吗?
以下文件可以在我的OS X机器上使用Python 2.6.7以及在SLES机器上使用ActivePython 2.6来重现该行为: webserver.py:
#!/usr/bin/env python
import SimpleHTTPServer
import SocketServer
import subprocess
import uuid
class MyRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_POST(self):
print 'in do_POST'
uuid_gen = str(uuid.uuid1())
subprocess.Popen(['python', 'sleep.py'])
print 'subprocess spawned'
return self.wfile.write(uuid_gen)
Handler = MyRequestHandler
server = SocketServer.TCPServer(('127.0.0.1', 9019), Handler)
server.serve_forever()
sleep.py:
import time
time.sleep(10)
当我现在启动网络服务器,然后对localhost:9019进行curl POST请求时,网络服务器立即打印:
$python2.6 webserver2.py
in do_POST
subprocess spawned
但在我执行curl请求的控制台上,它显示以下行为:
$curl -X POST http://127.0.0.1:9019/
<wait ~10 seconds>
cd8ee24a-0ad7-11e3-a361-34159e02ccec
当我使用Python 2.7运行相同的设置时,答案立即到达卷曲网站。 怎么会发生这种情况,因为Popen似乎并没有阻止印刷,只是回归? 问题是由于遗留原因我必须使用python 2.6,那么让该请求立即返回的最佳解决方法是什么?
答案 0 :(得分:0)
好的,所以在Nikhil向我推荐这个问题后https://stackoverflow.com/questions/3973789/...我发现我需要self.send_response(200),self.send_header(“Content-Length”,str(len(uuid_gen)))和self.end_headers()。
这意味着工作代码如下所示:
#!/usr/bin/env python
import SimpleHTTPServer
import SocketServer
import subprocess
import uuid
class MyRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_POST(self):
print 'in do_POST'
uuid_gen = str(uuid.uuid1())
subprocess.Popen(['python', 'sleep.py'])
print 'subprocess spawned'
self.send_response(200)
self.send_header("Content-Length", str(len(uuid_gen)))
self.end_headers()
self.wfile.write(uuid_gen)
Handler = MyRequestHandler
server = SocketServer.TCPServer(('127.0.0.1', 9019), Handler)
server.serve_forever()
问题似乎是为Pipelining开放了HTTP连接,尽管我仍然不确定为什么它会在Popen进程完成后完全返回。