Cython 中哪些 C 函数不需要 gil?
Which C functions are not gil-requiring in Cython?
我尝试编译以下 Cython
代码,它使用 C
函数进行文件操作:
import tempfile
from libc.stdio cimport *
cdef extern from "stdio.h":
FILE *fopen(const char *, const char *)
int fclose(FILE *)
size_t fwrite(const void *, size_t, size_t, FILE *)
ssize_t getline(char **, size_t *, FILE *)
def run_io():
cdef int ntasks
cdef int i
cdef string dump = "Some string"
cdef string content = ""
cdef char* fname
cdef FILE* cfile
cdef char* line = NULL
cdef size_t l = 0
tmpfile = tempfile.NamedTemporaryFile('w+')
fname = tmpfile.name.encode("UTF-8")
with nogil:
cfile = fopen(fname, "wb")
#fwrite(dump.data(), 1, dump.size(), cfile)
#fclose(cfile)
#cfile = fopen(fname, "rb")
#if getline(&line, &l, cfile) == -1:
#break
#else:
#printf("%s", line)
fclose(cfile)
tmpfile.close()
但是,我收到以下错误:
Error compiling Cython file:
------------------------------------------------------------
...
#cfile = fopen(fname, "rb")
#if getline(&line, &l, cfile) == -1:
#break
#else:
#printf("%s", line)
fclose(cfile)
^
------------------------------------------------------------
test.pyx:31:14: Calling gil-requiring function not allowed without gil
我认为只有 python
函数需要 gil 而不是导入的 C
函数。然而,似乎并非如此。
因此,我的问题是:
- 哪些C函数可以在
Cython
中使用而没有GIL
?
- 如何在没有
GIL
的情况下制作文件 read/write?
您正在隐藏 libc.stdio
中使用
声明的声明
cdef extern from "stdio.h" nogil:
使用您自己的定义,而没有 nogil
。回答标题中的问题:只有 Python/C API 函数需要 gil。
这是您的代码,导入正确并删除了任何不相关的内容:
import tempfile
from libc.stdio cimport fopen, fclose, fwrite, getline, FILE
from libcpp.string cimport string
def run_io():
cdef string dump = b"Some string"
tmpfile = tempfile.NamedTemporaryFile('w+')
cdef bytes py_fname = tmpfile.name.encode("UTF-8")
cdef char* fname = py_fname
cdef FILE* cfile
with nogil:
cfile = fopen(fname, "wb")
fclose(cfile)
tmpfile.close()
以下内容是确保延长 tmpfile.name.encode
返回的 temporary 的生命周期所必需的。
cdef bytes py_fname = tmpfile.name.encode("UTF-8")
cdef char* fname = py_fname
用
编译时没有报错
cython -3 --cplus my_mod.pyx
g++ my_mod.cpp -shared -o my_mod.so $(python3.4 --cflags --ldflags)
我尝试编译以下 Cython
代码,它使用 C
函数进行文件操作:
import tempfile
from libc.stdio cimport *
cdef extern from "stdio.h":
FILE *fopen(const char *, const char *)
int fclose(FILE *)
size_t fwrite(const void *, size_t, size_t, FILE *)
ssize_t getline(char **, size_t *, FILE *)
def run_io():
cdef int ntasks
cdef int i
cdef string dump = "Some string"
cdef string content = ""
cdef char* fname
cdef FILE* cfile
cdef char* line = NULL
cdef size_t l = 0
tmpfile = tempfile.NamedTemporaryFile('w+')
fname = tmpfile.name.encode("UTF-8")
with nogil:
cfile = fopen(fname, "wb")
#fwrite(dump.data(), 1, dump.size(), cfile)
#fclose(cfile)
#cfile = fopen(fname, "rb")
#if getline(&line, &l, cfile) == -1:
#break
#else:
#printf("%s", line)
fclose(cfile)
tmpfile.close()
但是,我收到以下错误:
Error compiling Cython file:
------------------------------------------------------------
...
#cfile = fopen(fname, "rb")
#if getline(&line, &l, cfile) == -1:
#break
#else:
#printf("%s", line)
fclose(cfile)
^
------------------------------------------------------------
test.pyx:31:14: Calling gil-requiring function not allowed without gil
我认为只有 python
函数需要 gil 而不是导入的 C
函数。然而,似乎并非如此。
因此,我的问题是:
- 哪些C函数可以在
Cython
中使用而没有GIL
? - 如何在没有
GIL
的情况下制作文件 read/write?
您正在隐藏 libc.stdio
中使用
cdef extern from "stdio.h" nogil:
使用您自己的定义,而没有 nogil
。回答标题中的问题:只有 Python/C API 函数需要 gil。
这是您的代码,导入正确并删除了任何不相关的内容:
import tempfile
from libc.stdio cimport fopen, fclose, fwrite, getline, FILE
from libcpp.string cimport string
def run_io():
cdef string dump = b"Some string"
tmpfile = tempfile.NamedTemporaryFile('w+')
cdef bytes py_fname = tmpfile.name.encode("UTF-8")
cdef char* fname = py_fname
cdef FILE* cfile
with nogil:
cfile = fopen(fname, "wb")
fclose(cfile)
tmpfile.close()
以下内容是确保延长 tmpfile.name.encode
返回的 temporary 的生命周期所必需的。
cdef bytes py_fname = tmpfile.name.encode("UTF-8")
cdef char* fname = py_fname
用
编译时没有报错cython -3 --cplus my_mod.pyx
g++ my_mod.cpp -shared -o my_mod.so $(python3.4 --cflags --ldflags)