我最好使用以下示例代码来解释我的问题:
while True: NewThread = threading.Thread(target = CheckSite, args = ("http://example.com", "http://demo.com")) NewThread.start() time.sleep(300) def CheckSite(Url1, Url2): try: Response1 = urllib2.urlopen(Url1) Response2 = urllib2.urlopen(Url2) del Response1 del Response2 except Exception, reason: print "How should I delete Response1 and Response2 when exception occurs?" del Response1 del Response2 #### You can't simply write this as Reponse2 might not even exist if exception shows up running Response1
我写了一个非常looong脚本,它用于检查不同的站点运行状态(响应时间或类似的东西),就像我在之前的代码中所做的那样,我使用几个线程分别检查不同的站点。正如你在每个线程中看到的那样,会有几个服务器请求,当然你会偶尔得到403或类似的。我一直认为那些浪费的连接(有异常的连接)会被python中的某种垃圾收集器收集,所以我就把它们留下来了。
但是当我检查我的网络监视器时,我发现那些浪费的连接仍然在那里浪费资源。脚本运行的时间越长,出现的连接浪费就越多。我真的不希望每次发送服务器请求时都执行try-except子句,以便del response
可以在每个except
部分中使用{{1}}来销毁浪费的连接。有一个更好的方法来做到这一点,任何人都可以帮助我吗?
答案 0 :(得分:3)
在这种情况下,你究竟期望“删除”是什么意思,无论如何,你希望实现什么?
Python具有自动垃圾收集功能。这些对象进一步定义,只要垃圾收集器到处收集相应的对象,就会关闭连接。
如果要确保在不再需要对象时立即关闭连接,可以使用with
构造。例如:
def CheckSite(Url1, Url2):
with urllib2.urlopen(Url1) as Response1:
with urllib2.urlopen(Url2) as Response2:
# do stuff
答案 1 :(得分:1)
我还建议将with语句与contextlib.closing
函数一起使用。
它应该在完成作业或获得异常时关闭连接。
类似的东西:
with contextlib.closing(urllib2.open(url)) as reponse:
pass
#del response #to assure the connection does not have references...
答案 2 :(得分:0)
你应该使用Response1.close()
。 with
不能直接与urllib2.urlopen
一起使用,但请参阅Python文档中的contextlib.closing示例。
由于TCP的可靠数据包传送功能,即使未正确关闭连接,连接仍可保持打开数小时,即使创建它们的进程已退出。
答案 3 :(得分:0)
您不应该检查Exception
,而应该抓住URLError
中提到的try:
Response1 = urllib2.urlopen(Url1)
Response2 = urllib2.urlopen(Url2)
Response1.close()
Response2.close()
except URLError, reason:
print "How should I delete Response1 and Response2 when exception occurs?"
if Response2 is not None:
Response2.close()
elif Response1 is not None:
Response1.close()
。
如果没有抛出异常,连接是否仍然存在?也许你正在寻找的是
def CheckSites(Url1, Url2):
try:
Response1 = urllib2.urlopen(Url1)
except URLError, reason:
print "Response 1 failed"
return
try:
Response2 = urllib2.urlopen(Url2)
except URLError, reason:
print "Response 2 failed"
## close Response1
Response1.close()
## do something or don't based on 1 passing and 2 failing
return
print "Both responded"
## party time. rm -rf /
但我不明白你为什么要在一次尝试中封装它们。我个人会这样做。
{{1}}
请注意,这样做会完成同样的事情,因为在您的代码中,如果Url1失败,您甚至都不会尝试打开Url2连接。
**旁注** 线程真的没有帮助你。您也可以按顺序尝试它们,因为一次只能运行一个线程。
Documentation
http://dabeaz.blogspot.com/2009/08/inside-inside-python-gil-presentation.html