这是一个由两部分组成的问题。第一个问题是如何正确关闭与urllib2的连接?我看到了很多例子,我已经采用了我能找到的最好的解决方案。但是,关闭文件时出现问题。在
当前我使用contextlib的closing()如下:
try:
with closing(self.opener.open(self.address,
None,
self.timeout)) as page:
self.data = page.read()
except:
# bail out..
然而,我在OSX上呆了很长时间后仍然会遇到“打开的文件太多”的错误。我使用ulimit将文件增加到2000或更高。我还将内核的max files设置为>;40000。我要注意的是,这个方法所定位的对象并没有被处理,它在程序的生命周期中一直存在。但是,我只保留存储在对象中的“数据”以及地址和超时。我不保存类似文件的对象。我认为问题可能是引用,但我不这么认为,因为我从不直接存储对文件类对象的引用,只存储read()中的数据。每次线程从队列中拉出一个url时,这些对象都会被重用并用新数据重新加载。在
我一次只打开大约50个连接。我不太明白我怎么会把文件用完。另外,当我用完文件时,netstat开始出现malloc错误:
^{pr2}$我也无法在不关机的情况下重新设置连接并使netstat恢复正常。在
netstat-m
$ netstat -m
475/3803 mbufs in use:
475 mbufs allocated to data
3328 mbufs allocated to caches
407/3814 mbuf 2KB clusters in use
0/577 mbuf 4KB clusters in use
0/12 mbuf 16KB clusters in use
11242 KB allocated to network (8.3% in use)
0 requests for memory denied
0 requests for memory delayed
0 calls to drain routines
我很难定位错误,但我相信连接没有及时关闭,我很清楚连接没有被重用,即使连接到一个域(我希望如此)。这是问题的第二部分。如何重用与urllib2的连接?在
我有多个线程从一个队列获取url,每个线程通过这种例程检索数据。如果可能的话,如果连接被另一个线程打开,我会重用它。线程之间唯一共享的数据是URL队列。我已经看过其他模块,但它们似乎需要更多的数据共享,而不仅仅是一个url。在
我建议放弃urllib2,尝试一下奇妙的Requests库。在
它会自动处理重用和关闭连接。(docs)
您可能还对它对异步请求的支持感兴趣。(docs)
相关问题 更多 >
编程相关推荐