Подтвердить что ты не робот

Являются ли urllib2 и httplib потоком безопасными?

Я ищу информацию о безопасности потоков urllib2 и httplib. Официальная документация (http://docs.python.org/library/urllib2.html и http://docs.python.org/library/httplib.html) не содержит никакой информации по этому вопросу; слово нить там даже не упоминается...

ОБНОВИТЬ

Хорошо, они не потокобезопасны из коробки. Что требуется, чтобы сделать их поточно-ориентированными или существует сценарий, в котором они могут быть поточно-ориентированными? Я спрашиваю, потому что кажется, что

  • используя отдельный OpenerDirector в каждом потоке
  • не разделяет HTTP-соединение между потоками

было бы достаточно безопасно использовать эти библиотеки в потоках. Аналогичный сценарий использования был предложен в вопросе urllib2 и безопасности потока cookielib

4b9b3361

Ответ 1

httplib и urllib2 не являются потокобезопасными.

urllib2 не предоставляет сериализованный доступ к глобальному (общему) объекту OpenerDirector, который используется urllib2.urlopen().

Точно так же httplib не обеспечивает сериализованный доступ к объектам HTTPConnection (т. HTTPConnection помощью потокового пула соединений), поэтому совместное HTTPConnection объектов HTTPConnection между потоками небезопасно.

Я предлагаю использовать httplib2 или urllib3 в качестве альтернативы, если требуется безопасность потоков.

Как правило, если в документации модуля не упоминается безопасность потоков, я бы предположил, что она не является потокобезопасной. Вы можете посмотреть исходный код модуля для проверки.

Просматривая исходный код, чтобы определить, является ли модуль поточно-ориентированным, вы можете начать с поиска использования примитивов синхронизации потоков из threading или multiprocessing модулей или использования queue.Queue.

ОБНОВИТЬ

Вот соответствующий фрагмент исходного кода из urllib2.py (Python 2.7.2):

_opener = None
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
    global _opener
    if _opener is None:
        _opener = build_opener()
    return _opener.open(url, data, timeout)

def install_opener(opener):
    global _opener
    _opener = opener

Существует очевидное условие urlopen() когда параллельные потоки вызывают install_opener() и urlopen().

Также обратите внимание, что вызов urlopen() с объектом Request в качестве параметра url может привести к изменению объекта Request (см. Источник OpenerDirector.open()), поэтому одновременный вызов urlopen() с общим объектом Request urlopen().

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

  • install_opener() не вызывается из другого потока.
  • В качестве параметра url используется неиспользуемый объект Request или строка.