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线程安全性提出了类似的使用情况

httpliburllib2 不是线程安全的。

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