这是一个关于在仍使用Python对象但仍受限制的方式下在CPython中释放GIL的问题。
出于性能方面的考虑,我需要跳入无GIL模式,同时保持对现有Python对象的只读访问权限。保证对象始终存在,并且没有其他线程对其进行突变(没有删除,追加等)。换句话说,它们对于所有实际目的都是“常量”,不需要引用计数,也不会进行动态分配。
假设输入中有一个本机Python对象,例如list
,dict
或int
。像往常一样,我们可以使用C API以PyObject *
的形式使用此对象。
问:释放GIL,然后在该对象上调用只读(“ const”)函数是否安全?例如,呼叫PyList_GET_ITEM(lst, 0)
,PyInt_AS_LONG(i)
或PyDict_GetItem(dct, key)
?
如果没有,为什么不呢?
更笼统地说,关于(缺少)对象突变和动态分配以及需要通过GIL进行同步的CPython合同是什么?
我创建了一个Python整数列表,然后释放了GIL,使用标准PyList_Size
和PyList_GET_ITEM
对列表元素进行了迭代,将内部的整数值求和,重新获得了GIL。一切正常,结果正确。由于没有创建,删除或变异任何Python对象,因此无需增加/减少任何内容。
但是这个实验当然不能证明-可能有副作用或局限性。