Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我会在Python BaseHTTPServer中看到随机读取错误?_Python_Http_Sockets_Concurrency_Mocking - Fatal编程技术网

为什么我会在Python BaseHTTPServer中看到随机读取错误?

为什么我会在Python BaseHTTPServer中看到随机读取错误?,python,http,sockets,concurrency,mocking,Python,Http,Sockets,Concurrency,Mocking,我有调用外部HTTP服务的Python代码。我想通过设置模仿这些外部服务的模拟HTTP服务器来测试这段代码。我通过在一个单独的线程中启动一个BaseHTTPServer,然后从主线程调用该服务器来实现这一点。看起来是这样的: import BaseHTTPServer, httplib, threading, time class MockHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_POST(self):

我有调用外部HTTP服务的Python代码。我想通过设置模仿这些外部服务的模拟HTTP服务器来测试这段代码。我通过在一个单独的线程中启动一个
BaseHTTPServer
,然后从主线程调用该服务器来实现这一点。看起来是这样的:

import BaseHTTPServer, httplib, threading, time

class MockHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_POST(self):
        self.send_response(200)
        self.send_header('Content-Type', 'application/json')
        self.end_headers()
        self.wfile.write('{"result": "success"}')

class ServerThread(threading.Thread):
    def run(self):
        svr = BaseHTTPServer.HTTPServer(('127.0.0.1', 8540), MockHandler)
        svr.handle_request()

ServerThread().start()
time.sleep(0.1)             # Give the thread some time to get up

conn = httplib.HTTPConnection('127.0.0.1', 8540)
conn.request('POST', '/', 'foo=bar&baz=qux')
resp_body = conn.getresponse().read()
但是,一些请求在
read()
调用中失败,导致
socket.error:[Errno 104]连接被对等方重置。我可以使用Python2.6在多台机器上以不同的频率复制它,但不能使用Python2.7

但最有趣的是,如果我不发送POST数据(即,如果我将第三个参数省略到
conn.request()
),则不会发生错误

这会是什么

或者,是否有另一种快速简便的方法在Python中设置模拟HTTP服务器?

“…在单独的线程中,然后从主线程调用该服务器。”

这种事情不要用线程


使用流程
subprocess.Popen(以及您的操作系统的正常功能)将在确保其正常工作方面做得更好。

@David Wolever:它们不是。线程共享大量I/O资源。当一个线程正在等待读取时,其他线程可能不一定会被调度,从而使HTTP库通过对等状态消息提供奇怪的连接重置。进程不共享任何内容,只允许I/O继续进行操作系统级的调度。线程应该只用于计算密集型的事情,而不是I/O的事情。这显然是I/O密集型。谢谢。我围绕
多处理
重写了模拟服务器,使用
队列
将服务器对请求的意见传递回测试用例。这是可行的,几乎和
线程化一样简单。然而,我必须承认我不明白这个问题的原因。此外,我曾经相信Python中的线程对于计算密集型任务是无用的,因为GIL与您所说的相反。我想我需要读一些有启发性的文档。@Vasiliy Faronov:“由于GIL,对于计算密集型任务毫无用处”。部分正确。不完全正确。这不是一个微不足道的区别。但是,您可以很容易地避免浪费时间来处理线程。使用
多处理