这是一个由两部分组成的问题。首先是如何正确关闭与 urllib2 的连接?我看过很多例子,并采用了我能找到的最佳解决方案。但是,关闭文件似乎出现问题。
目前我使用 contextlib 的 opening() 如下:
try:
with closing(self.opener.open(self.address,
None,
self.timeout)) as page:
self.data = page.read()
except:
# bail out..
但是,在 OSX 上运行很长时间后,我仍然收到“打开文件过多”错误。我使用 ulimit 将文件增加到 2000 及以上。我还将内核的最大文件数设置为 >40,000。我应该注意,该方法所在的对象不会被释放,并且在程序的生命周期中仍然存在。但是,我只保留存储在对象中的“数据”以及地址和超时。我不存储类似文件的对象。我认为问题可能是引用,但我不这么认为,因为我从不直接存储对类文件对象的引用,只存储来自 read() 的数据。每次线程从队列中提取 URL 时,这些对象都会被重用并重新加载新数据。
我一次只打开大约 50 个连接。我不太明白我怎么会用完文件。另外,当我用完文件时,netstat 开始出现 malloc 错误:
netstat(439) malloc: *** mmap(size=18446744073708605440) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
netstat: malloc 18446744073708605396 bytes: Cannot allocate memory
我也找不到一种方法来重置连接并使 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。
最佳答案
关于python - 如何关闭与 urllib2 的连接并重用连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9961774/