我正在寻找有关urllib2和httplib的线程安全性的信息。 官方文件(http://docs.python.org/library/urllib2.html和http://docs.python.org/library/httplib.html)缺乏关于此主题的任何信息;那里甚至没有提到线程这个词...
更新
好的,它们不是开箱即用的线程安全的。 是什么使它们成为线程安全的,或者是否存在可以线程安全的场景? 我问,因为它似乎是
OpenerDirector
足以在线程中安全地使用这些库。问题urllib2 and cookielib thread safety
中提出了类似的使用场景答案 0 :(得分:41)
httplib
和urllib2
不是线程安全的。
urllib2
不提供对全局(共享)的序列化访问
OpenerDirector
使用的urllib2.urlopen()
对象。
类似地,httplib
不提供对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
并发线程调用install_opener()
和urlopen()
时存在明显的竞争条件。
另请注意,使用urlopen()
对象作为Request
参数调用url
可能会改变Request
对象(请参阅OpenerDirector.open()
的来源),因此,同时使用共享的urlopen()
对象调用Request
是不安全的。
总而言之,如果满足以下条件,urlopen()
是线程安全的:
install_opener()
未从其他线程调用。Request
对象或字符串用作url
参数。