在一般情况下,C 库需要PyEval_InitThreads()在生成任何调用 python 回调的线程之前调用以获取 GIL。并且回调需要用PyGILState_Ensure()和包围PyGILState_Release()以确保安全执行。
然而,如果 C 库运行在 python C 扩展的上下文中,那么在一些简单的情况下,完全省略 GIL 操作是安全的。
想一想这个调用顺序:1) python 代码调用 C 函数foo(),2)foo()生成一个且唯一一个运行另一个 C 函数的线程bar(),该函数回调 python 代码,3)foo()始终在返回之前加入或取消正在运行的线程bar()。
在这种情况下,忽略 GIL 操作是安全的。因为在其生命周期内foo() 拥有GIL(即从调用它的python代码中隐式借用),并且生命周期内python回调的执行foo()是序列化的(即只有一个回调线程并且python代码不合并threading)。