我有一个C ++类,其中一些方法使用std :: thread,我可以通过Cython访问Python。你知道在我的Cython代码中我想要把nogill指令放在哪里吗?当我声明类方法或创建Cython包装类时,我想要它吗?我使用了以下Cython文档中的示例类:
声明课程:
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle() except +
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getArea()
void getSize(int* width, int* height)
void move(int, int)
Cython包装类:
cdef class PyRectangle:
cdef Rectangle c_rect # hold a C++ instance which we're wrapping
def __cinit__(self, int x0, int y0, int x1, int y1):
self.c_rect = Rectangle(x0, y0, x1, y1)
def get_area(self):
return self.c_rect.getArea()
def get_size(self):
cdef int width, height
self.c_rect.getSize(&width, &height)
return width, height
def move(self, dx, dy):
self.c_rect.move(dx, dy)
答案 0 :(得分:6)
您可能实际上需要才能使用nogil
。 GIL只会阻止多个Python线程同时运行。但是,如果你使用C ++线程,他们可以很高兴地在后台运行而不管GIL,只要他们不尝试使用PyObject
或运行Python代码。所以我怀疑你是否误解了GIL,你可以不去思考它。
但是,假设您确实想要发布它,您需要做两件事:
将C ++函数标记为nogil
告诉Cython他们不需要GIL。请注意,这并没有实际释放它 - 它只是让Cython知道它不是一个问题,如果它被释放:
cdef cppclass Rectange:
Rectangle(int, int, int, int) nogil except +
int getArea() nogil
# ...
使用Cython包装器类中的with nogil:
块来标记实际释放GIL的区域。
cdef class PyRectangle:
# ...
def __cinit__(self, int x0, int y0, int x1, int y1):
with nogil:
self.c_rect = Rectangle(x0, y0, x1, y1)
def get_area(self):
cdef int result
with nogil:
result = self.c_rect.getArea()
return result
get_area
变得稍微复杂一些,因为返回语句不能存在于with nogil
块中,因为它涉及生成Python对象。