Python线程和GIL

时间:2011-01-20 15:11:26

标签: python multithreading locking gil

我正在阅读关于GIL的内容并且它从未真正指定是否包含主线程(我假设如此)。我问的原因是因为我有一个带有线程设置的程序来修改字典。主线程基于播放器输入添加/删除,而线程循环数据更新和更改数据。

但是在某些情况下,线程可以遍历字典键,可以删除它们。如果有一个所谓的GIL并且它们按顺序运行,为什么我会更改dict更改错误?如果只假设一次运行,那么从技术上讲,这不应该发生。

任何人都可以对这样的事情有所了解吗?谢谢。

4 个答案:

答案 0 :(得分:10)

他们同时正在运行,他们只是不同时执行。迭代可能是交错的。引用Python:

  

CPython解释器用来确保一次只有一个执行 Python 字节码的机制。

所以两个for循环可能同时运行,同时没有(例如)两个del dict[index]

答案 1 :(得分:5)

GIL锁定在Python字节码级别,并且适用于所有线程,甚至是主线程。如果你有一个线程修改字典和另一个迭代键,它们会相互干扰。

“一次只运行一次”是正确的,但您必须了解粒度单位。对于CPython的GIL,粒度是字节码指令,因此执行可以在任何字节码的线程之间切换。

答案 2 :(得分:3)

gil阻止两个线程同时修改解释器状态。它不提供任何线程一致性约束,或任何类型的互斥体,其粒度小于整个过程。如果您需要在两个线程中读取和修改dict,则应该使用互斥锁

答案 3 :(得分:1)

Python比你想象的更频繁地切换线程。你说“只有一个”应该一次运行,从技术上说这是真的,但这取决于你对“一个”的定义。 Python的原子操作非常小。例如:将单个项目添加到字典中。可以中断对整个字典的迭代。

您应该使用threading库中的锁定对象来隔离程序的原子操作。