在cython中使用nogil和cpdef类方法

Mar*_*rdi 4 parallel-processing cython

我想设计一个cdef类,其方法可以并行运行,因此我需要将它们设置为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
Run Code Online (Sandbox Code Playgroud)

虽然同样cdef int incr会有效.这有点令人惊讶,因为在正常cpdef函数nogil中允许属性:

cpdef int testfunc(int x) nogil:
    return x + 1
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么或做错了吗?

Dav*_*idW 7

如果你看一下生成的C代码(省略nogil),你会发现该方法所做的第一件事就是检查它是否被Python子类覆盖了.这需要GIL.

(请注意,对于cdef函数来说,这不可能发生,因为Python从未知道它,所以那里没有问题.)

幸运的是,它很容易使你的Cython类不能被子类化并且问题消失(它编译得很好nogil):

cimport cython

@cython.final
cdef class Test:
    # the rest of your code is exactly the same so isn't reproduced...
Run Code Online (Sandbox Code Playgroud)