Python GIL 和线程同步
阅读了各种解释 Python 中的 GIS 和线程的文章后,由于 GIL,多线程 Python 代码中不需要锁吗? 这是一个非常有用的答案,我有一个“最后一个问题”。
理想情况下,如果我的线程仅通过 原子(Python VM)指令,例如将一个项目追加到列表中,不需要锁,对吗?
After having read various articles that explain GIS and threads in Python, and Are locks unnecessary in multi-threaded Python code because of the GIL? which is a very useful answer, I have one "last question".
If, ideally, my threads only operate on shared data through atomic (Python VM) instructions, e.g. appending an item to a list, a lock is not needed, right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这实际上取决于您的应用程序。就像在任何其他语言中一样,您可能需要为您的特定用例提供锁,但您不需要保护 python 对象无论如何都会被损坏。从这个意义上说,你不需要锁。
下面的示例使用了一堆几乎原子操作,但当您组合它们时仍然可能会出现意想不到的行为。
线程 1:
线程 2:
如果线程 2 在线程 1 的第一条语句和最后一条语句之间运行,则线程 1 只是删除了错误的工作项。所有 python 对象都没有损坏或发生任何问题,但您仍然得到意外结果,并且可能会引发异常。
如果你有共享的数据结构,你通常需要用锁来保护它们,或者更好地使用已经编写的受保护版本,就像在这种情况下可能是一个队列: http://docs.python.org/library/queue.html
That really depends on your application. You may need locks for your specific use case just like in any other language, but you don't need to protect the python objects getting corrupted anyway. In that sense you don't need locks.
Here's an example that uses a bunch of pretty much atomic operations, but can still behave in unexpected ways when you combine them.
Thread 1:
Thread 2:
If Thread 2 runs in between the first and last statement of Thread 1, then Thread 1 just deleted the wrong work item. None of the python objects are corrupt or anything, but you still got an unexpected result, and potentially exceptions could be thrown.
If you have shared data structures, you usually need to protect them with locks, or even better use already written protected versions, like in this case maybe a Queue: http://docs.python.org/library/queue.html
理论上不是,但这取决于逻辑,例如,当您保持顺序时,您需要锁。
In theory not, but it depends on the logic, you need a lock when you are preserving order, for example.
当您在线程之间共享数据时,您应该始终确保数据正确同步,因为您不能依赖将来操作是否是原子的。
从一开始就正确设计多线程比尝试修复由于实现更改或错误假设而导致的问题要容易得多。
When you share data between threads, you should always make sure your data is properly synchronized because you cannot rely on wether operations will be or not atomic in the future.
It is easier to get the multi-threading design right in the first place than try to fix something that breaks because of a change in implementation or a wrong assumption.
谢谢大家的回答!
很明显,线程同步要求与应用程序逻辑绑定在一起,但我可以依靠 GIL 来不会破坏内置对象的内部结构(操作是原子的)。我不清楚我何时说 GIL 保护解释器的“内部状态”、其内部数据结构......我的意思是,这是一种效果,但 GIL 保护每个分配的内置结构,无论是对象还是对象由解释器的内部操作和应用程序创建的对象创建和使用。这是我的疑问。
PS:很抱歉这么晚才回复,但我没有收到电子邮件通知......
Thanks everyone for the answers!
It's clear that thread sync requirements are bound to the application logic, but I can rely on the GIL to do not corrupt the builtin objects internals (is the operations are atomic). It wasn't clear to me when the GIL i said to protect the "internal state" of the interpreter, its internal data structures... I mean, this is an effect, but the GIL protects every allocated builtin structure, both for objects created and used by internal operations of the interpreter and objects created by the application. That was my doubt.
PS: I'm sorry for having answered so late, but I didn't receive email notifies...