我正在修改一个嵌入Python的库,需要使用子解释器以支持重置Python状态,同时避免调用
我对该库略有了解,但我越来越发现一些地方使用
切换到子解释器后,我几乎立即在调用
“值得一提的是,我已经验证了在调用PyGILState_Ensure之前确实会执行调用PyEval_RestoreThread的行(在上面的图片中第一次调用Python之前很久就执行了)。
我正在使用Python 3.8.2。显然,文档没有说谎,它说:
请注意,PyGILState_*函数假定只有一个全局解释器(由Py_Initialize()自动创建)。Python支持创建额外的解释器(使用Py_NewInterpreter()),但混合多个解释器和PyGILState_* API是不受支持的。
重构库以便内部跟踪是否保留了GIL是相当麻烦且相当愚蠢的。应该有一种方法来确定是否保留了GIL!但是,我能找到的唯一函数是PyGILState_Check,但它是禁止使用的PyGILState API的成员。我不确定它是否有效。是否有一种规范的方法在子解释器中执行此操作?”
Py_Finalize
(因为之后调用Py_Initialize
是不可取的)。我对该库略有了解,但我越来越发现一些地方使用
PyGILState_Ensure
和其他PyGILState_*
函数来获取GIL以响应某些外部回调。其中一些回调来自Python外部,因此我们的线程肯定没有持有GIL,但有时回调来自于Python内部,因此我们肯定持有GIL。切换到子解释器后,我几乎立即在调用
PyGILState_Ensure
时看到了死锁,因为它调用了PyEval_RestoreThread
,尽管显然已经从Python内部执行(因此持有GIL):
![stack trace at the point of deadlock](https://istack.dev59.com/usY4P.webp)
我正在使用Python 3.8.2。显然,文档没有说谎,它说:
请注意,PyGILState_*函数假定只有一个全局解释器(由Py_Initialize()自动创建)。Python支持创建额外的解释器(使用Py_NewInterpreter()),但混合多个解释器和PyGILState_* API是不受支持的。
重构库以便内部跟踪是否保留了GIL是相当麻烦且相当愚蠢的。应该有一种方法来确定是否保留了GIL!但是,我能找到的唯一函数是PyGILState_Check,但它是禁止使用的PyGILState API的成员。我不确定它是否有效。是否有一种规范的方法在子解释器中执行此操作?”