使用 Cython 命名临时文件

Named temporary files with Cython

我正在寻找 tempfile.NamedTemporaryFile() 函数的 C 模拟,以便在没有 GIL 的情况下并行使用 Cython 代码。理论上 tmpnam 函数可以解决问题:

from cython import parallel
from libc.stdio cimport FILE, tmpnam, fopen, fclose, fwrite
from libcpp.string cimport string

cdef save_obj(string obj):
    cdef char* fname
    cdef FILE* cfile
    with nogil, parallel.parallel():
        fname = tmpnam(NULL)
        cfile = fopen(fname, "wb")
        fwrite(obj.data(), 1, obj.size(), cfile)
        fclose(cfile)

但是,由于某种原因,它仍然无法正常工作,因为我在编译过程中遇到以下错误:

    with nogil, parallel.parallel():
        fname = tmpnam(NULL)
                      ^
------------------------------------------------------------

testc2.pyx:9:23: Converting to Python object not allowed without gil

我不明白,这个python对象来自哪里,因为函数来自C

谁能解释一下,为什么 tmpnam 仍然需要 GIL,我该如何解决这个问题?

Cython 用于导入本机函数(如 C 标准库中的函数)的所有信息均来自 pxd 文件中的信息,这些文件类似于头文件。 Cython 为 C 标准库头文件捆绑了几个 pxd 文件,包括 stdio.pxd link。这就是您在代码的第二行导入的内容。

如果您检查 link,您会发现 tmpnam 未在捆绑的 stdio.pxd 中定义,因此 Cython 猜测您使用的是 Python 在该上下文中的名称。您仍然可以导入该函数,但您必须提供一个原型:

cdef extern from "stdio.h" nogil:
   char* tmpnam(char*);