在 cython 中使用 nogil 和 cpdef class 方法

Using nogil with cpdef class method in cython

我想设计一个cdef class,其方法可以运行并行,因此我需要将它们设置为nogil。我看到我可以对 cdef 方法执行此操作,但出于某种原因我无法理解我不允许对 cpdef 方法执行相同的操作。这尤其失败

cdef class Test:
    cdef int i
    def __init__(self):
        self.i = 0
    cpdef int incr(self) nogil:
        self.i += 1;
        return self.i

虽然与 cdef int incr 相同也可以。这有点令人惊讶,因为在正常的 cpdef 函数中 nogil 属性是允许的:

cpdef int testfunc(int x) nogil:
    return x + 1

我是不是遗漏了什么或者做错了什么?

如果您查看生成的 C 代码(省略 nogil),您会发现该方法所做的第一件事是检查它是否已被 Python 子程序覆盖class。这需要 GIL。

(请注意,cdef 函数不会发生这种情况,因为 Python 永远不知道它,所以这里没有问题。)

幸运的是,很容易让你的 Cython class 无法被子classed 并且问题消失了(它可以用 nogil 编译):

cimport cython

@cython.final
cdef class Test:
    # the rest of your code is exactly the same so isn't reproduced...