关于python的GIL

2023-07-31  本文已影响0人  wangfp

讨论GIL离不开gc

1. 引用计数:

引用计数在一个对象的强引用数量降为0是自动触发对象回收,类似于Rust的变量在离开作用域时或引用计数变为0时触发Drop()。该回收操作实际上是在代码运行中的附加操作。
(Cython的gc实际上不是处理不再使用的对象,而是处理可能存在的循环引用)

2. 标记/清除 etc.

这类gc是在程序运行一段时间或者内存使用到达一定阈值的情况下触发的,一般通过stw来执行gc,清理不再使用的对象来释放内存。分代只是优化这类gc的一种策略

所以实际上Cython在执行的时候是不会触发stw的。但作为解释性语言,每次读取一条指令,然后执行一条指令,在允许多线程同时进行解释执行的情况下很容易导致同一个对象的引用计数不准确(针对这种情况Rust专门设计了俩种智能指针:Rc,Arc来分别处理串行和并行时的引用计数问题)。为了避免这种状况,Cython采取的办法是在执行每条指令前加上一个锁(GIL),并执行后释放,这就导致整个python代码在执行期间实际上是串行。
Cython的多进程可以跳过GIL的原因是进程间的数据是隔离的(包含引用计数)。

对于Jython而言,使用VM对python语句进行解释,所以使用的是标记/清除方式的gc,从而不需要GIL也可以保证变量的及时清理

总结:

GIL是和python语言的解释器相关的,本质是由于选择的gc策略不同

参考资料:

上一篇下一篇

猜你喜欢

热点阅读