Python:GIL上下文 - 切换

Cha*_*l72 8 c python cpython python-c-api python-3.x

所以,我通常非常了解Python中的全局解释器锁(GIL)是如何工作的.本质上,当解释器正在运行时,一个线程将GIL保存为N个刻度(N可以使用设置sys.setcheckinterval),此时GIL被释放而另一个线程可以获取GIL.如果一个线程开始I/O操作,也会发生这种情况.

我有点困惑的是这一切是如何与C扩展模块一起工作的.

如果你有一个C扩展模块获取GIL,然后使用执行一些python代码PyEval_EvalCode,解释器是否可以释放GIL并将其提供给其他线程?或者获取GIL的C线程是否会永久保留GIL,直到PyEval_EvalCode返回并且GIL在C中明确释放?

PyGILState gstate = PyGILState_Ensure();

....

/* Can calling PyEval_EvalCode release the GIL and let another thread acquire it?? */
PyObject* obj = PyEval_EvalCode(code, global_dict, local_dict); 

PyGILState_Release(gstate);
Run Code Online (Sandbox Code Playgroud)

Arm*_*igo 4

是的,解释器总是可以释放GIL;它会在解释了足够的指令后将其交给其他线程,或者在执行一些 I/O 时自动将其交给其他线程。请注意,自最近的 Python 3.x 以来,标准不再基于执行的指令数量,而是基于是否已经过去了足够的时间。

为了获得不同的效果,您需要一种以“原子”模式获取 GIL 的方法,方法是要求在显式释放 GIL 之前不要释放它。到目前为止这是不可能的(但请参阅https://bitbucket.org/arigo/cpython-withatomic以获得实验版本)。