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
参数。