Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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是线程安全的吗?_Python_Regex - Fatal编程技术网

Python是线程安全的吗?

Python是线程安全的吗?,python,regex,Python,Regex,我试着用谷歌搜索,但没有得到权威的答案 有人能确认re模块 线程安全吗 更具体地说,哪些功能是,哪些不是 另外,我是否可以重用单个全局编译的re对象来跨线程安全地执行sub、搜索等操作 似乎仍然没有明确的答案? 好的,一个更具体的例子: class MyClass: GLOBAL_VAR = re.compile(...) def clean(self, value): return MyClass.GLOBAL_VAR.sub('', value)

我试着用谷歌搜索,但没有得到权威的答案

有人能确认
re
模块 线程安全吗

更具体地说,哪些功能是,哪些不是

另外,我是否可以重用单个全局编译的re对象来跨线程安全地执行
sub
搜索
等操作

似乎仍然没有明确的答案?

好的,一个更具体的例子:

  class MyClass:
     GLOBAL_VAR = re.compile(...)

     def clean(self, value):
        return MyClass.GLOBAL_VAR.sub('', value) 

当多个线程同时调用clean时,这会像预期的那样工作吗?

是的,它们是线程安全的,因为函数之间只有一个缓存字典,每个函数将使用它查找生成的值,如果值不在缓存中,函数将生成值并将其放入缓存字典,而且它不会违反线程安全

我认为除了在源代码中挖掘之外,没有权威的答案,它可以为现有版本的Python提供答案,但不一定是未来版本的Python,因为正则表达式模块的某些版本至少有一部分是用C编写的(至少对CPython来说,比如对Jython来说,谁知道呢?)


在实践中,我没有看到任何不是线程安全的代码,您稍后使用
GLOBAL\u VAR.sub
调用的示例“几乎可以肯定”是线程安全的。但是…仍然缺少书面承诺。:-

我想您可能需要阅读。Python(至少是最常见的解释器CPython)并没有从多线程中真正获益(除非在执行I/O绑定操作时)。@elmo:GIL并没有使Python库线程安全@J.F.Sebastian:没错,不过我希望所有的库都表现得理智(尤其是标准库)。如果他们释放GIL,这意味着他们知道自己在做什么(是线程安全的)。所以我假设事实上所有的东西都是线程安全的(如果不是,我会认为它是一个bug),因为吉尔。请注意,这些都是基于我对Python仍然有限的知识而做出的假设,因此,如果我错了,请纠正我。@elmo:我提到了通过
regex
模块发布GIL,只是为了表明Python可能真的从多线程中受益(即使在执行CPU限制的操作时)。这与线程安全问题是正交的。一切都不是线程安全的,除非模块文档这样说,或者您已经检查了源代码并证明您对实现的使用是线程安全的。公平地说,stdlib模块很少被记录为线程安全的,即使有一些使用模式允许从多个线程安全地使用模块,而无需任何额外的同步。整数是不可变的()。假设一个模块有一个全局
i=1
,还有一个方法
incr()
,该方法执行
i=i+1
。现在,对
incr()
的两个调用应该将
i
设置为
3
。但是如果通过不同的线程调用,您可能会得到
i=2
(如果两个线程都在
1
时读取
i
的值)。所以,您只有不可变的对象,但这不是线程安全的。@E先生。但是,您的模块不是不可变的。在工作期间,模块将通过以下方式进行更改:thread@Mr.E. 整个复杂的添加和替换操作都不是线程安全的。这个问题不是很好,因为很容易给出一个使用
re
的非线程安全代码示例,例如,为某个RegexObject设置一个全局值,然后读取它(这与您的示例相同)。然而,正如Pooya指出的,在一个RegexObject中不可能做到这一点。对于整数也是如此。它们也是线程安全的。线程不安全的是涉及一个以上整数的操作。@freakish:我的例子只是为了说明不能像答案中提到的那样,仅仅“因为所有函数和对象都是不可变的”,就说明模块是线程安全的。Pooya,我也相信它是线程安全的,但关键是1)它与不变性无关(因此,您的答案可能是正确的,但推理是错误的);2)您只能通过查看完整的源代码给出“权威”的答案。我只存储编译后的版本。我希望文档能够保证线程安全。