我python程序使用httplib2.Http发出http请求。一旦需要生成请求,我就创建一个httplib2.Http对象,这样我的程序就可以频繁地创建/销毁httplib2.Http对象。
我发现我的程序很容易崩溃,因为达到了打开文件的最大数量。正在检查/proc//fd,打开的套接字fd太多。这个问题让我不得不深入研究httplib2源代码。
然后我发现,在httplib2.Http._conn_request方法中,有这样的代码:
else:
content = ""
if method == "HEAD":
conn.close()
else:
content = response.read()
response = Response(response)
if method != "HEAD":
content = _decompressContent(response, content)
break这表明只有当http方法为HEAD时,套接字才会关闭。也许httplib2想以某种方式重用套接字。但是Http类没有close()方法。这意味着当我发出Http请求时,套接字不会关闭,直到我的进程终止。
然后我修改了代码:
else:
content = ""
if method == "HEAD":
conn.close()
else:
content = response.read()
response = Response(response)
if method != "HEAD":
content = _decompressContent(response, content)
conn.close() # I ADD THIS CLOSE
break在那之后,我的程序运行得很好。
但我仍然很好奇,鉴于httplib2是一个非常古老和常见的库,这是否真的是httplib2的错误。
发布于 2013-05-22 17:58:33
不,连接没有关闭的事实不是bug,有必要为下一个请求重用连接。
按照httplib2的编写方式,它会等待服务器关闭连接或超时,而不会主动关闭它们(错误时除外)。如果连接已经关闭,httplib2将在下次使用时尝试重新建立连接。
关闭连接(就像你的补丁一样)将使这变得不可能,每个请求都必须使用它自己的连接。
销毁httplib2.Http对象应该会自动关闭打开的连接,因为它们只在它的connections字典中被引用,所以如果您没有保留对您创建的Http对象的任何引用,那么它应该可以工作。你确定你周围没有任何推荐人吗?
或者,您可以将Connnection: close头传递给您的请求:
http.request("http://example.org", headers={'Connection': 'close'})这将导致服务器在每次请求后关闭连接。或者,您可以尝试手动关闭对象的connections字典中的所有连接。
https://stackoverflow.com/questions/16687033
复制相似问题