使用 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*);
我正在寻找 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*);