【问题标题】:Python GIL and threads synchronizationPython GIL 和线程同步
【发布时间】:2011-08-17 20:17:46
【问题描述】:

在阅读了各种解释 GIS 和 Python 线程的文章以及非常有用的答案 Are locks unnecessary in multi-threaded Python code because of the GIL? 之后,我有一个“最后一个问题”。

如果理想情况下,我的线程仅通过atomic (Python VM) instructions 对共享数据进行操作,例如将项目附加到列表中,不需要锁,对吗?

【问题讨论】:

  • 不要使用链接缩短器。此外,本网站上其他问题的链接会自动替换为问题的标题。

标签: python multithreading gil


【解决方案1】:

这实际上取决于您的应用程序。就像在任何其他语言中一样,您可能需要针对特定​​用例的锁,但无论如何您都不需要保护 python 对象被损坏。从这个意义上说,您不需要锁。

这是一个使用大量原子操作的示例,但是当您将它们组合起来时,仍然会以意想不到的方式运行。

线程 1:

v = l[-1]
DoWork(v]
del l[-1]

线程 2:

l.append(3)

如果线程 2 在线程 1 的第一条和最后一条语句之间运行,那么线程 1 只是删除了错误的工作项。 python 对象都没有损坏或任何东西,但您仍然得到意外结果,并且可能会引发异常。

如果你有共享数据结构,你通常需要用锁来保护它们,或者更好地使用已经编写好的保护版本,比如在这种情况下可能是一个队列:http://docs.python.org/library/queue.html

【讨论】:

    【解决方案2】:

    理论上不会,但取决于逻辑,例如在保留顺序时需要一个锁。

    【讨论】:

      【解决方案3】:

      当您在线程之间共享数据时,您应该始终确保您的数据正确同步,因为您不能依赖未来的操作是否是原子的。

      一开始就正确设计多线程比尝试修复由于实现更改或错误假设而中断的问题更容易。

      【讨论】:

        【解决方案4】:

        感谢大家的回答! 很明显,线程同步要求与应用程序逻辑绑定,但我可以依靠 GIL 来不破坏内置对象的内部结构(操作是原子的)。当我说 GIL 保护解释器的“内部状态”时,我不清楚它的内部数据结构......我的意思是,这是一种效果,但 GIL 保护每个分配的内置结构,包括对象由解释器的内部操作和应用程序创建的对象创建和使用。这是我的疑问。

        PS:很抱歉这么晚才回复,但我没有收到电子邮件通知...

        【讨论】: