Python代码调用创建OS线程的C库,最终调用Python回调

phu*_*tor 5 c python pthreads callback

如果操作系统调度另一个调用Python回调的线程时,唯一的Python解释器正在执行字节码,那么会发生什么?我是否有理由担心这种设计的可靠性?

liu*_*uyu 3

在一般情况下,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)。

  • 我同意,如果 Python 中只有一个线程(没有 GIL)并且 C 线程按顺序访问 Python 函数,那么它应该可以工作。否则[可能会出现错误。我创建了一个小型 C 扩展模块来演示它](https://gist.github.com/3471699)。 (2认同)
  • @Sebastian,刚刚查看了您的演示。我相信 KeyError 和死锁情况是可以避免的。看看这个 https://gist.github.com/3473376 (2认同)