我有一段代码,我有一个处理线程和一个监视器线程。在处理线程中,我调用了collections.deque.popleft函数。我想知道这个函数是否释放GIL,因为我想运行我的监视器线程,即使在popleft函数上阻止了处理函数
答案 0 :(得分:1)
我没有回答这个具体问题,而是回答一个不同的问题:
什么是Global Interpreter Lock (GIL),什么时候会阻止我的程序?
简而言之,GIL保护解释器的状态不被并发线程损坏。
为了了解 的含义,请考虑dict
的低级实现,其中某个地方有一个键组,用于快速查找。当你写一些代码时:
myDict['foo'] = 'bar'
python解释器需要调整其键集合。这可能涉及诸如为附加密钥腾出更多空间以及向该阵列添加特定密钥之类的事情。
如果多个并发线程正在修改该dict,那么一个线程可能会重新分配该阵列,而另一个线程正在修改它,这可能会导致一些不可预测的,可能是坏的行为(来自损坏的数据,段错误或像内存一样的内容)敏感数据的内容泄漏或任意代码执行)
由于这不是你可以在你的python应用程序级别合理地描述或阻止的那种状态,因此运行时会竭尽全力防止出现这类问题。它的方式是解释器的某些部分,例如dict的修改,被PyGILState_Ensure()
/ PyGILState_Release()
对包围,因此关键操作总是达到一致状态。
但请注意,此锁的范围非常窄;它不会试图保护免受一般数据争用,它不会保护你不会编写一个程序,多个线程在一个公共容器中覆盖彼此的工作(比如一个collections.deque
),只有这样做即使你这样做编写这样的程序,它不会导致解释器崩溃,你将始终拥有一个有效的工作deque
。您可以添加其他应用程序锁,如queue.Queue
中所示,以便为您的应用程序提供良好的并发语义。
由于GIL保护的每个操作都是解释器状态的变化,因此它永远不会阻止外部事件;由于这些事件不会导致解释器状态发生变化,因此信号条件变量不会破坏内存。
你可能遇到问题的唯一一次是当你有几个解除阻塞的线程时,因为它们可能都在低级解释器中执行代码,它们将竞争GIL,而且只有一个线程可以保持它,阻止其他想要进行一些计算的线程。
除非您正在编写C扩展,否则您可能不需要担心它,除非您在
答案 1 :(得分:-1)
是的 - deque
是线程安全的(感谢@hemanths)http://docs.python.org/2/library/collections.html#collections.deque
不,因为 collections.deque
不是线程安全的。使用Queue,或创建自己的deque
子类。