【问题标题】:How to release the GIL in Cython for a multithreaded C++ class?如何在 Cython 中为多线程 C++ 类发布 GIL?
【发布时间】:2017-08-03 10:37:36
【问题描述】:

我有一个 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)

【问题讨论】:

    标签: python c++ multithreading cython gil


    【解决方案1】:

    您可能实际上需要使用nogil。 GIL 只停止多个 Python 线程同时运行。但是,如果您使用的是 C++ 线程,它们可以很高兴地在后台运行而不管 GIL,只要它们不尝试使用 PyObjects 或运行 Python 代码。所以我怀疑你误解了 GIL,你可以不去想它。

    但是,假设您确实想要发布它,您需要做两件事:

    1. 将 C++ 函数标记为 nogil 以告诉 Cython 他们不需要 GIL。请注意,这实际上并没有释放它 - 它只是让 Cython 知道如果它被释放它不是问题:

      cdef cppclass Rectange:
         Rectangle(int, int, int, int) nogil except +
         int getArea() nogil
         # ...
      
    2. 在 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 变得稍微复杂一些,因为 return 语句不能存在于 with nogil 块中,因为它涉及生成 Python 对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多