为什么我必须担心CPython中的线程安全性?

据我所知,全局解释器锁只允许一个线程访问解释器并执行字节码。 如果是这样的话,那么在任何时候,只有一个线程会使用解释器和它的内存。

因此,我认为排除出现种族情况的可能性是公平的,因为没有两个线程可以同时访问解释器的内存,但我仍然看到有关确保数据结构“线程安全”的警告。 有可能它会覆盖python解释器的所有实现(比如cython),它可以关闭GIL并允许真正的多线程。

我了解在没有启用GIL的解释器环境中线程安全的重要性。 但是,对于CPython,为什么在编写多线程Python代码时鼓励线程安全? 在CPython环境中会发生什么更糟?


当然,竞争条件仍然可以发生,因为访问数据结构不是原子的。

假设您测试字典中存在的密钥,然后执行以下操作来添加密钥:

if key not in dictionary:
    # calculate new value
    value = elaborate_calculation()
    dictionary[key] = value

线程可以在任何时候在not in测试的状态下返回true,并且另一个线程也会得出结论:钥匙不在那里。 现在有两个线程正在进行计算,而你不知道哪一个会赢。

GIL所做的就是保护Python的内部解释器状态。 这并不意味着Python代码本身使用的数据结构现在被锁定和保护。


一个重要的注意事项:尽管GIL,Python中的多处理模块在一定程度上是同步的,因为对同一变量的访问可以同时发生在不同的进程中。

这有可能破坏你的数据,或者至少干扰你的控制流,这就是线程安全的原因。

至于为什么会发生,尽管只有一个interpriter,但没有任何事情停止(至少据我所知),两个预先编入代码的代码片段可以同时访问共享内存的相同部分。 当说话时:

import multiprocessing
def my_func ():
    print("hello world")
my_process=multiprocessing.Process (target=my_func, args=(,))
my_process.start ()
my_process.join ()

我的理解是,interprit(在这种情况下)my_func花费的时间被埋在了产生新进程的开销中。

在这种情况下,术语“进程”在这里更适合,因为有些工作线程是为了复制数据而暂时产生的,所以有一些数据握手正在进行,所以它实际上是一个不同的进程(双关意图)比传统线程的产卵。

我希望这有帮助。

链接地址: http://www.djcxy.com/p/15169.html

上一篇: Why Do I have to worry about Thread Safety in CPython?

下一篇: PyPy significantly slower than CPython