无法在C类型扩展迭代中删除gil

时间:2017-06-22 05:44:59

标签: python cython

我不明白为什么我会收到错误说:

  

在没有gil的情况下不允许丢弃拥有的Python对象

我的代码是C类型扩展,所以它不应该是Python对象,但在这种情况下我不能应用nogil。对于为什么会这样,我有点无能为力。

cdef class Fraction:

    cdef int _numerator
    cdef int _denominator
    cdef int numerator
    cdef int denominator

    def __cinit__(self, numerator=0, denominator=None, bint _normalize=True):

        self._numerator = numerator
        self._denominator = denominator


@cython.boundscheck(False) 
@cython.wraparound(False) 
cpdef gaussian_inverse_cy():

    cdef int a = 1, b = 2, i

    with nogil: 
        for i in prange(10000):
            Fraction(a,b) 

1 个答案:

答案 0 :(得分:0)

cdef class定义了新的Python扩展类。从它们创建的对象是Python对象,需要创建或操作GIL。

如果你想要的是一个可以在没有GIL的情况下使用的C结构,相反,不在Python中公开,可以使用结构并将其映射到扩展类。

例如:

from libc.stdlib cimport malloc, free
from cython.parallel cimport prange

ctypedef struct _Fraction:
    int numerator
    int denominator

cdef _Fraction * create_fraction(int numerator, int denominator) nogil:
    # Example, needs error checking, freeing, etc
    _fraction = <_Fraction *>malloc(sizeof(_Fraction))
    _fraction.numerator = numerator
    _fraction.denominator = denominator
    return _fraction

cpdef gaussian_inverse_cy():
    cdef int a = 1, b = 2, i
    with nogil:
        for i in prange(10000):
            my_fract = create_fraction(a,b)
            # <do something with my_fract>

上面编译并运行正常,但显然没有任何东西作为Python对象返回。

要将分数结构暴露给Python,您可以为其创建一个使用_Fraction *成员的扩展类,例如:

cdef class Fraction:     cdef _Fraction * _fraction     &LT; ..&GT;

在创建对象后,将_fraction指定为_Fraction结构的C指针。