Add a way to define functions that always run without the GIL
See original GitHub issueWhen working with C and C++ extensions, is common to have functions that must run without the GIL held (for instance, to make sure there are no deadlocks that involve other locks or native threads). This can be easily achieved doing:
cdef void my_func_wrapper(...):
with nogil:
my_func(...)
The problem is that when exposing a large library or multiple methods and classes that fall in this situation, you end with tons of tons of wrappers like the one before, which feels very verbose and unnecessary
Cython already offers a solution for the opposite problem (taking the GIL always when the function is called) using the with gil
declaration:
cdef void my_func_wrapper(...) with gil
but there is no obvious way that I know to achieve the contrary (the original case I am discussing to drop always the GIL).
For this reason, I propose to add an analogous with nogil
qualifier to function declarations:
cdef void my_func_wrapper(...) with nogil
that basically generates the following code:
static double __pyx_f_3fib_my_func(void) {
#ifdef WITH_THREAD
PyThreadState *_save;
Py_UNBLOCK_THREADS
__Pyx_FastGIL_Remember();
#endif
// FUNCTION CODE HERE //
/* function exit code */
#ifdef WITH_THREAD
__Pyx_FastGIL_Forget();
Py_BLOCK_THREADS
#endif
}
I have a draft PR if everyone agrees that this is a desired feature to add.
Also, if someone thinks the feature is good but the naming may confuse people as “nogil” already exists, we could explore other possibilities like:
- Adding instead a decorator like
@cython.with_no_gil
or similar. - Some other keyword like
nevergil
instead.
Issue Analytics
- State:
- Created 4 years ago
- Comments:21 (15 by maintainers)
Top GitHub Comments
Ah, right. 😃 I keep forgetting about the stuff that I fix over time …
@McSinyx the declarations are more like this:
nogil
: assumes the GIL not be be held on entry (although it may be) and prevents the function body from using operations that require the GIL (except for operations that explicitly or implicitly acquire the GIL). Requires a C function signature.with gil
: assures that the GIL is held during the function body, regardless of whether it was released before or not. Same as thewith gil:
context manager around the complete function body together with anogil
function declaration. Requires a C function signature.with nogil
: assures that the GIL is released around the function body, regardless of whether it was held before or not. Same as thewith nogil:
context manager around the complete function body. When used ondef
andcpdef
functions, the Python function wrapper will always require the GIL to be held on entry.cdef
functions and the C entry point ofcpdef
functions will automatically be marked asnogil
and can thus be called directly fromnogil
code.The last bit is something that may require a bit more work on top of Pablo’s current WIP branch.