Ответ 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
или строка.