Cython技术问题:如何向nogil修饰的cdef函数传递numpy内存视图
问题原因与解决方案
出现访问违规的核心原因是:在nogil块内将numpy数组隐式转换为内存视图的操作需要GIL。numpy数组本质是Python对象,转换为内存视图时需要做类型校验、引用计数维护等依赖GIL的操作,强行在无GIL环境下执行就会触发内存访问错误。
要保留nogil并解决问题,只需把numpy数组到内存视图的转换步骤移到nogil块之外(即有GIL的环境中),再在无GIL区域传递已转换好的内存视图:
cdef int function(int[:,:] ref) nogil: pass cpdef test(): cdef np.ndarray[int, ndim=2] ref = np.full((10,10),0) # 先在GIL环境下完成numpy数组到内存视图的转换 cdef int[:,:] ref_view = ref with nogil: # 直接传递已转换好的内存视图,无需再做Python对象操作 function(ref_view)
关键说明
- 内存视图本身是C级别的结构,不依赖Python对象,所以在
nogil块内传递和操作是安全的。 - 只有从numpy数组(Python对象)转换为内存视图的过程需要GIL,必须在
with nogil:之前完成。
内容的提问来源于stack exchange,提问作者spamEggsAndSpam
相关产品推荐
相关产品推荐

