Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python urllib2和httplib是线程安全的吗?_Python_Thread Safety_Urllib2_Httplib - Fatal编程技术网

Python urllib2和httplib是线程安全的吗?

Python urllib2和httplib是线程安全的吗?,python,thread-safety,urllib2,httplib,Python,Thread Safety,Urllib2,Httplib,我正在查找有关urllib2和httplib的线程安全性的信息。 官方文件(和)缺少关于该主题的任何信息;这里甚至没有提到线程这个词 更新 好的,它们不是线程安全的开箱即用。 要使它们成为线程安全的,需要什么?或者是否存在一种可以实现线程安全的场景? 我这么问是因为看起来 在每个线程中使用单独的 不在服务器之间共享HTTP连接 线程 在线程中安全地使用这些lib就足够了。类似的使用场景也在讨论中提出httplib和urlib2是线程安全的 urllib2不提供对全局(共享)文件的序列化访问

我正在查找有关
urllib2
httplib
的线程安全性的信息。 官方文件(和)缺少关于该主题的任何信息;这里甚至没有提到线程这个词

更新

好的,它们不是线程安全的开箱即用。 要使它们成为线程安全的,需要什么?或者是否存在一种可以实现线程安全的场景? 我这么问是因为看起来

  • 在每个线程中使用单独的
  • 不在服务器之间共享HTTP连接 线程

在线程中安全地使用这些lib就足够了。类似的使用场景也在讨论中提出

httplib
urlib2
是线程安全的

urllib2
不提供对全局(共享)文件的序列化访问
OpenerDirector
对象,该对象由
urlib2.urlopen()
使用

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

如果需要线程安全性,我建议使用或作为替代方案

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

在浏览源代码以确定模块是否是线程安全的时,您可以 可以从查找线程同步原语的用法开始
线程化
多处理
模块,或使用
队列.队列

更新

以下是
urllib2.py
(Python 2.7.2)中的相关源代码片段:

当并发线程调用
install\u opener()
urlopen()
时,存在明显的争用情况

另外,请注意,使用
Request
对象作为
url
参数调用
urlopen()
,可能会使
Request
对象发生变异(请参阅源代码),因此使用共享
Request
对象同时调用
urlopen()
是不安全的

总之,如果满足以下条件,
urlopen()
是线程安全的:

  • install\u opener()
    不是从另一个线程调用的
  • 非共享的
    请求
    对象或字符串用作
    url
    参数

@Gregg-您能谈谈如何通过检查特定模块的代码来确定线程安全性吗?我经常有这样一个确切的问题…@ire_和_诅咒:我相应地扩展了我的答案。强迫用户检查库的源代码以确定给定库是否是线程安全的想法对我来说很奇怪。有些库使用同步代码而不是线程安全的(cookielib),有些库不使用同步代码而是线程安全的,因为它们使用无锁结构和算法。@Piotr Dobrogost:我同意不应该强迫用户检查库的源代码以确定它是否是线程安全的。如果开发库时考虑到线程安全,那么我假设文档会指出这一点。如果文档没有谈到线程安全,那么我假设库不是线程安全的。为了验证我的假设,通常需要浏览一下库的代码。关于无锁数据结构和cookielib,线程安全是一个复杂的主题,我只提供了一个在模块中查找的基线,这可能表明它是线程安全的。这是真的吗?代码中有一个共享的OpenDirector对象,但是HTTP请求将由HTTPHandler处理,它没有任何有意义的状态。因此,每次open()调用最终都会产生一个新的HTTPConnection对象(第1116行,urllib2.py)。因此,在这一点上,HTTPConnection对象是否是线程安全的并不重要,因为每次调用urllib2.open都会有一个不同的实例。这似乎支持:。从这个角度看,当事情不是线程安全的时候,他们也会记录下来。
_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