6

我正在阅读有关 GIL 的信息,但它从未真正指定这是否包括主线程(我假设是这样)。我问的原因是因为我有一个带有修改字典的线程设置的程序。主线程根据玩家输入添加/删除,而线程循环数据更新和更改数据。

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

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

4

4 回答 4

10

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

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

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

于 2011-01-20T15:16:46.900 回答
6

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

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

于 2011-01-20T15:15:48.787 回答
3

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

于 2011-01-20T15:17:00.633 回答
1

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

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

于 2011-01-20T15:19:27.273 回答