I try to compile the following Cython
code, which uses C
functions for file operations:
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()
However, I get the following error:
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
I thought that only python
functions are gil-requiring but not imported C
ones. Nevertheless, it seems like it is not so.
Therefore, my questions are:
- Which C functions can be used in
Cython
withoutGIL
? - How to make file read/write without
GIL
?
You are shadowing the declarations from
libc.stdio
which are declared withwith your own definitions which do not have
nogil
. To answer the question in your title: only Python/C API functions require the gil.This is your code with correct imports and trimmed of anything not relevant:
The following is necessary to ensure that the lifetime of the temporary returned by
tmpfile.name.encode
is extended.It gives no errors when compiled with