urllib2和httplib线程安全吗?

时间:2011-04-28 21:17:57

标签: python thread-safety urllib2 httplib

我正在寻找有关urllib2和httplib的线程安全性的信息。 官方文件(http://docs.python.org/library/urllib2.htmlhttp://docs.python.org/library/httplib.html)缺乏关于此主题的任何信息;那里甚至没有提到线程这个词...

更新

好的,它们不是开箱即用的线程安全的。 是什么使它们成为线程安全的,或者是否存在可以线程安全的场景? 我问,因为它似乎是

  • 在每个帖子中使用单独的OpenerDirector
  • 之间不共享HTTP连接 线程

足以在线程中安全地使用这些库。问题urllib2 and cookielib thread safety

中提出了类似的使用场景

1 个答案:

答案 0 :(得分:41)

httpliburllib2 是线程安全的。

urllib2不提供对全局(共享)的序列化访问 OpenerDirector使用的urllib2.urlopen()对象。

类似地,httplib不提供对HTTPConnection个对象的序列化访问(即通过使用线程安全的连接池),因此在线程之间共享HTTPConnection对象是不安全的。

如果需要线程安全,我建议使用httplib2urllib3替代。

通常,如果模块的文档没有提到线程安全性,我会认为它不是线程安全的。您可以查看模块的源代码以进行验证。

在浏览源代码以确定模块是否是线程安全的时候 可以从查找线程同步原语的使用开始 threadingmultiprocessing个模块,或使用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参数。