【问题标题】:Can't remove gil on a C type extension iteration无法在 C 类型扩展迭代中删除 gil
【发布时间】:2017-06-22 05:44:59
【问题描述】:

我不明白为什么我收到一条错误消息:

在没有 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) 

【问题讨论】:

  • 确实是一个 Python 对象。 cdef 类让您创建一个新的内置 Python 类型 docs.cython.org/en/latest/src/userguide/… ,没有 gil 就无法创建/操作。
  • 您可以将它放在一个小的with gil: 块中。显然,在这种情况下,这将是整个循环,但在实际示例中,它可能只是循环的一小部分。我认为您应该仍然能够在没有 GIL 的情况下访问 cdef 属性(一旦创建)。
  • @MLhacker 看看这是否有帮助:stackoverflow.com/a/21135087/6037118

标签: python cython


【解决方案1】:

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

如果你想要的是一个可以在没有 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 类分数: cdef _Fraction *_fraction <..>

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2016-07-29
    相关资源
    最近更新 更多