看来,由于访问NumPy数组数据不需要调用
Python解释器,C扩展可以在释放GIL后操作这些数组.例如,在
this thread.
内置的Python类型bytearray支持Buffer Protocol,其中一个成员是
void *buf
A pointer to the start of the logical structure described by the
buffer fields. […]
For contiguous arrays,the value points to the beginning of the memory
block.
我的问题是,在发布GIL(Py_BEGIN_ALLOW_THREADS)后,C扩展是否可以操作此buf,因为访问它不再需要调用Python C API?或者Python垃圾收集器的性质是否禁止这样做,因为在执行期间可能会移动bytearray及其buf?
解决方法
为了澄清作为注释写的简短答案:您可以在不保存GIL的情况下访问* buf数据,前提是您确定Py_buffer结构在没有GIL的情况下由线程“拥有”.
为了完整起见,我应该补充一点,这可能会打开(非常远程)崩溃风险的大门:如果无GIL线程在* buf读取数据,同时另一个GIL持有线程正在运行Python代码更改相同的数据(bytearray [index] = x),然后无GIL的线程可以看到其脚下数据的意外更改.相反的情况也是如此,甚至更烦人(但仍然是理论上的):如果无GIL的线程在* buf处更改数据,那么其他持有GIL的,运行Python的线程可能会看到奇怪的结果,甚至可能会在执行某些操作时崩溃复杂的读取操作,如bytearray.split().