urllib2和httplib线程安全吗?
我正在寻找有关urllib2和httplib的线程安全性的信息。 官方文档( http://docs.python.org/library/urllib2.html和http://docs.python.org/library/httplib.html )缺less关于此主题的任何信息; 字线甚至没有提到那里…
UPDATE
好的,它们不是线程安全的。 需要什么使它们成为线程安全的,或者是否有一种可以线程安全的scheme? 我问,因为这似乎是
- 在每个线程中使用单独的
OpenerDirector - 不在线程之间共享HTTP连接
足以安全地在线程中使用这些库。 问题urllib2和cookielib线程安全性提出了类似的使用情况
httplib和urllib2 不是线程安全的。
urllib2不提供对由OpenerDirector urllib2.urlopen()使用的全局(共享) OpenerDirector对象的序列化访问。
同样, httplib不提供对HTTPConnection对象的序列化访问(即通过使用线程安全连接池),所以在线程之间共享HTTPConnection对象是不安全的。
如果需要线程安全,我build议使用httplib2或urllib3作为替代。
一般来说,如果一个模块的文档没有提到线程安全性,我会认为它不是线程安全的。 您可以查看模块的源代码进行validation。
在浏览源代码以确定某个模块是否是线程安全的时,可以先从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()时,会有明显的竞争条件。
另外,请注意,使用Request对象作为url参数调用urlopen()可能会改变Request对象(请参阅OpenerDirector.open()的源代码),因此使用共享Request对象同时调用urlopen()是不安全的。
总而言之,如果满足以下条件,则urlopen()是线程安全的:
-
install_opener()不从另一个线程调用。 - 一个非共享的
Request对象或string被用作url参数。