Cython 中的这个声明是啥? cdef PyObject **工人。它是指向指针的指针吗?

Posted

技术标签:

【中文标题】Cython 中的这个声明是啥? cdef PyObject **工人。它是指向指针的指针吗?【英文标题】:What is this declaration in Cython? cdef PyObject **workers. Is it a pointer to a pointer?Cython 中的这个声明是什么? cdef PyObject **工人。它是指向指针的指针吗? 【发布时间】:2020-09-05 15:26:13 【问题描述】:

我正在尝试利用此 sample code 中的概念并行运行一些 Cython 代码,但我似乎无法在 Cython 文档中找到有关此表示法实际含义的任何信息。

    cdef FLOAT_t[:] numbers
    cdef unsigned int i
    cdef INDEX_t n_workers
    cdef PyObject **workers
    cdef list ref_workers #Here to maintain references on Python side
    
    def __init__(Parent self, INDEX_t n_workers, list numbers):
        cdef INDEX_t i
        self.n_workers = n_workers
        self.numbers = np.array(numbers,dtype=float)
        self.workers = <PyObject **>malloc(self.n_workers*cython.sizeof(cython.pointer(PyObject)))
        
        #Populate worker pool
        self.ref_workers = []
        for i in range(self.n_workers):
            self.ref_workers.append(Worker())
            self.workers[i] = <PyObject*>self.ref_workers[i]
    
    def __dealloc__(Parent self):
        free(self.workers)

** 表示法是否意味着它是指向 PyObject 指针的指针?我知道&lt;&gt; 表示法是为了取消引用指针,这一行也是:

self.workers = &lt;PyObject **&gt;malloc(self.n_workers*cython.sizeof(cython.pointer(PyObject)))

分配未知数量的内存,因为直到 self.workers 被取消引用的 PyObjects 填充之前,PyObject 的大小是未知的?

【问题讨论】:

【参考方案1】:

它不仅是指向 PyObject* 指针的指针,还是指向 PyObject* 指针数组的第一个元素的指针。

您可以看到它正在分配内存以容纳self.n_workers,大概是使用 PyObject 派生类实现的,因此在内存中您将拥有:

self.workers -> self.workers[0] (PyObject* for 1st worker)
                self.workers[1] (PyObject* for 2nd worker)
                ....
                self.workers[N-1]  (PyObject* for last worker)

【讨论】:

我认为 OP 的另一个问题是,他们将 dereferece-operator (*) 与 void * 通过 PyObject ** 转换为 PyObject ** 混淆。 啊,是的,你说得对,&lt;&gt; 表示强制转换而不是取消引用,这是通过 [0] 语法完成的(尽管我不知道如何使用指向指针的指针)。最终,我正在尝试调整此代码以用于解决类似问题以利用 prange (因为父类能够使用工作类对象),但此示例代码实际上需要更长的时间来并行运行而不是在连载! @stagermane 如果您尝试通过 Cython 并行运行 Python 代码,您可能会不走运;我相信 GIL 可以防止发生多处理。 @Den-Jason,能够解决这个问题,但是您可以通过释放 GIL 与 Cython 并行运行,您的函数只需要没有 python 对象。

以上是关于Cython 中的这个声明是啥? cdef PyObject **工人。它是指向指针的指针吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机回调中使用 Cython cdef 类成员方法

如何在 cdef 中等待?

如何分析 cdef 函数?

『Python CoolBook』Cython

在cdef类中混合使用cdef和常规python属性

写。 Anaconda Python 3.4 和 Cython