我在用着cytpes
包装 C api。其中一个 api 函数允许您注册回调。我在用着CFUNCTYPE
to 指定函数的类型并创建一个实例CFUNCTYPE
来自我的 python 库的用户提供的 python 函数,然后我将其传递给 C 函数(使用ctypes
api).
我知道ctypes
调用释放GIL
。我想知道当 C 库函数调用我的 python 回调函数时会发生什么。做ctypes
重新获得GIL
?
The 文档 says:
Note:确保保留对以下内容的引用CFUNCTYPE()
对象,只要它们是从 C 代码中使用的。ctypes
不,如果不这样做,它们可能会被垃圾收集,从而在进行回调时使您的程序崩溃。
另请注意,如果在 Python 控制之外创建的线程中调用回调函数(例如,通过调用回调的外部代码),ctypes
每次调用时都会创建一个新的虚拟 Python 线程。此行为对于大多数用途来说都是正确的,但这意味着存储的值threading.local
即使这些调用是从同一个 C 线程进行的,也不会在不同的回调中生存。
它没有说任何关于GIL
。这是否意味着一切都为我处理了?
The CThunkObject回调中引用的_objects
属性有pcl_exec
C 库调用的函数指针。这段代码调用closure_fcn参考 thunk 以及调用args
和一个指向内存的指针来存储结果。闭包函数依次调用_CallPythonObject, 与 thunk 的restype
, setfunc
, callable
, converters
, and flags
作为参数。第一件事_CallPythonObject
确实是打电话PyGILState_Ensure获取 GIL。即使这是 Python 第一次看到当前线程,这也有效。
换句话说,一切都为你处理好了。只需保留对回调的引用即可保持 thunk 的引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)