【问题标题】:Why does subprocess.Popen block the response of SimpleHTTPServer.SimpleHTTPRequestHandler为什么 subprocess.Popen 会阻塞 SimpleHTTPServer.SimpleHTTPRequestHandler 的响应
【发布时间】:2013-08-22 03:13:23
【问题描述】:

我有一个奇怪的问题,如果在请求处理程序中由 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 运行相同的设置时,答案会立即出现在 curl 站点上。 这怎么会发生,因为 Popen 似乎并没有阻止打印,而只是阻止了返回? 问题是由于遗留原因我必须使用 python 2.6,那么让请求立即返回的最佳解决方法是什么?

【问题讨论】:

  • 谢谢。没看到那个。但是发送内容长度的答案并不能真正解决问题。 curl 立即打印标题(内容长度),但大约 10 秒后 uuid 仍然到达。
  • self.send_response(200) 和 content-length 标头似乎可以解决问题。

标签: python blocking popen python-2.6 simplehttpserver


【解决方案1】:

好的,所以在 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()

问题似乎是 HTTP 连接对流水线保持打开状态,尽管我仍然不太确定为什么它会在 Popen 进程完成时返回。

【讨论】:

    猜你喜欢
    • 2014-12-27
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2021-06-10
    • 2017-07-14
    • 1970-01-01
    • 2019-05-22
    相关资源
    最近更新 更多