httplib
и urllib2
не потокобезопасны.
urllib2
не обеспечивает сериализованный доступ к глобальной (общей)
OpenerDirector
объект, который используется urllib2.urlopen()
.
Аналогичным образом, httplib
не обеспечивает сериализованный доступ к HTTPConnection
объектам (т. Е. С помощью потокового пула соединений), поэтому совместное использование HTTPConnection
объектов между потоками небезопасно.
Я предлагаю использовать httplib2 или urllib3 в качестве альтернативы, если требуется безопасность потоков.
Как правило, если в документации модуля не упоминается потокобезопасность , я бы предположил, что он не потокобезопасен. Вы можете посмотреть исходный код модуля для проверки.
При просмотре исходного кода, чтобы определить, является ли модуль потокобезопасным, вы
можно начать с поиска использования примитивов синхронизации потоков из
threading
или multiprocessing
модулей, или использование queue.Queue
.
UPDATE
Вот соответствующий фрагмент исходного кода из 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
Существует очевидное состояние гонки, когда параллельные потоки вызывают install_opener()
и urlopen()
.
Также обратите внимание, что вызов urlopen()
с объектом Request
в качестве параметра url
может привести к изменению объекта Request
(см. Источник для OpenerDirector.open()
), поэтому это не так. безопасно одновременно вызывать urlopen()
с общим Request
объектом.
Все сказано, urlopen()
является поточно-ориентированным, если выполняются следующие условия:
install_opener()
не вызывается из другого потока.
- A объект
Request
без общего доступа или строка используется в качестве параметра url
.