如何关闭连接并重用与urllib2的连接?

时间:2012-04-01 03:56:47

标签: python urllib2

这是一个两部分问题。第一个是如何正确关闭与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文件设置为> 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队列。我查看了其他模块,但它们似乎需要更多的数据共享而不仅仅是一个网址。

1 个答案:

答案 0 :(得分:3)

我建议删除urllib2,并尝试使用精彩的Requests库。

它会自动负责重用和关闭连接。 (docs

您可能也对它支持发出异步请求感兴趣。 (docs