繁体   English   中英

collections.deque“ pop”方法会释放GIL吗?

[英]Will the collections.deque “pop” methods release GIL?

我有一段代码,其中有一个处理线程和一个监视器线程。 在处理线程中,我调用了collections.deque.popleft函数。 我想知道此函数是否释放GIL,因为即使处理函数在popleft函数上被阻止,我也要运行我的监视器线程

除了回答这个特定问题外,我将回答另一个问题:

什么是全局解释器锁(GIL) ,什么时候它将阻止我的程序?

简而言之,GIL保护解释器的状态不被并发线程破坏。

为了了解它的用途 ,请考虑dict的低级别实现,该实现在某个地方具有一组键,可以快速查找。 当您编写如下代码时:

myDict['foo'] = 'bar'

python解释器需要调整其键集合。 这可能涉及诸如为附加键腾出更多空间以及向该数组添加特定键之类的事情。

如果多个并发线程正在修改该指令,则一个线程可能会重新分配该数组,而另一个线程可能正在修改该数组,这可能会导致某些不可预测的行为,可能是不良的行为(任何数据损坏,segfault或令人讨厌的事情,例如内存内容泄漏)。敏感数据或任意代码执行)

由于这不是您可以在python应用程序级别上合理描述或阻止的状态,因此运行时会竭尽全力以防止发生此类问题。 这样做的方式是,解释器的某些部分(如字典的修改PyGILState_Ensure()PyGILState_Ensure() / PyGILState_Release()对包围,因此关键操作始终会达到一致状态。

但是请注意,此锁定的范围非常狭窄。 它不会尝试避免受到一般数据争用的侵害,也不会保护您避免编写具有多个线程的程序,这些程序会在一个公共容器(例如collections.deque )中覆盖彼此的工作,即使您确实编写了这样的程序一个程序,它不会导致解释器崩溃,您将始终有一个有效的工作deque 您可以像在queue.Queue一样添加其他应用程序锁, queue.Queue应用程序提供良好的并发语义。

由于GIL保护的每个操作都是解释器状态的变化,因此它永远不会在外部事件上阻塞; 由于这些事件不会导致解释器状态更改,因此信令条件变量不会破坏内存。


可能唯一的问题是,当您有几个不受阻塞的线程时,因为它们可能都是低级解释器中正在执行的代码,它们将争夺GIL,并且只有一个线程可以容纳它,从而阻塞了其他线程。想做一些计算。

除非您正在编写C扩展,否则您可能不必担心它,并且除非您在python中具有多个计算绑定线程,否则也不会受到它的影响。

是- deque是线程安全的(感谢@hemanths) http://docs.python.org/2/library/collections.html#collections.deque

不可以,因为 collections.deque不是线程安全的。 使用 Queue ,或创建自己的 deque子类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM