5

似乎由于访问 NumPy 数组数据不需要调用 Python 解释器,因此 C 扩展可以在释放 GIL 后操作这些数组。例如,在这个线程中。

内置的 Python 类型 bytearray 支持Buffer Protocol,其中一个成员是

无效*buf

指向缓冲区字段描述的逻辑结构开始的指针。[...] 对于连续数组,值指向内存块的开头。

我的问题是,在释放 GIL (Py_BEGIN_ALLOW_THREADS) 后,C 扩展是否可以操作此buf,因为访问它不再需要调用 Python C API?或者 Python 垃圾收集器的性质是否禁止这样做,因为 bytearray 及其 buf 可能在执行期间被移动?

4

1 回答 1

3

为了澄清写成评论的简短答案:您可以在不持有 GIL 的情况下访问 *buf 数据,前提是您确定 Py_buffer 结构在没有 GIL 的情况下运行时由线程“拥有”。

为了完整起见,我应该补充一点,这可能会为(非常遥远的)崩溃风险打开大门:如果无 GIL 线程在 *buf 读取数据,而同时另一个持有 GIL 的线程正在运行 Python 代码更改相同的数据 (bytearray[index]=x) 然后 GIL-less 线程可以看到其脚下数据的意外更改。反之亦然,甚至更烦人(但仍然是理论上的):如果无 GIL 线程更改 *buf 处的数据,那么其他持有 GIL、运行 Python 的线程可能会看到奇怪的结果,甚至可能在执行某些操作时崩溃复杂的读取操作,例如 bytearray.split()。

于 2012-11-06T11:25:55.153 回答