Как вы закрываете соединения и повторно используете соединения с urllib2? - PullRequest
2 голосов
/ 01 апреля 2012

Это вопрос из двух частей. Во-первых, как правильно закрыть соединение с urllib2? Я видел несколько примеров, и я принял лучшее решение, которое я мог найти. Однако при закрытии файлов возникает проблема.

В настоящее время я использую закрытие contextlib () следующим образом:

    try:
        with closing(self.opener.open(self.address, 
                                      None, 
                                      self.timeout)) as page:
            self.data = page.read()
    except:
        # bail out..

Тем не менее, я все еще получаю ошибку «слишком много открытых файлов» после долгого времени на OSX. Я использовал ulimit для увеличения файлов до 2000 и выше. Я также установил максимальные файлы ядра до> 40000. Должен заметить, что объект, к которому относится этот метод, не утилизируется и остается на всю жизнь программы. Однако я сохраняю только «данные», хранящиеся в объекте, а также адрес и время ожидания. Я не храню файловый объект. Я думал, что проблема может быть в ссылках, но я не верю в это, потому что я никогда не храню ссылку на файловый объект напрямую, только данные из 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.

1 Ответ

3 голосов
/ 01 апреля 2012

Я бы порекомендовал сбросить urllib2 и попробовать фантастическую библиотеку Requests .

Она автоматически позаботится о повторном использовании и закрытии соединений.( docs )

Возможно, вам также будет интересна поддержка асинхронных запросов.( 1010 * документы *)

...