question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add a way to define functions that always run without the GIL

See original GitHub issue

When 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:open
  • Created 4 years ago
  • Comments:21 (15 by maintainers)

github_iconTop GitHub Comments

1reaction
scodercommented, Mar 20, 2020

I tested first; no such warning occurred.

Ah, right. 😃 I keep forgetting about the stuff that I fix over time …

1reaction
scodercommented, Mar 19, 2020

@McSinyx the declarations are more like this:

  • ‘gil’: GIL is assumed to be held, normal Python function behaviour, thus no special keyword
  • 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 the with gil: context manager around the complete function body together with a nogil 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 the with nogil: context manager around the complete function body. When used on def and cpdef functions, the Python function wrapper will always require the GIL to be held on entry. cdef functions and the C entry point of cpdef functions will automatically be marked as nogil and can thus be called directly from nogil code.

The last bit is something that may require a bit more work on top of Pablo’s current WIP branch.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using function pointers to methods of classes without the gil
The best workround I have is to use ctypes (or possibly also cffi) which can turn any Python callable into a function pointer....
Read more >
Release the GIL - speice.io
We'll define a “busy work” function that demonstrates this ... (with and without GIL) take effectively the same amount of time to run....
Read more >
Running python on multiple threads? - Google Groups
From C code I execute cython callback that is defined "with gil", it runs fine until I call some pure python function -...
Read more >
What Is the Python Global Interpreter Lock (GIL)?
No, each core runs (usually) 2 threads. That's at the bare circuit level. The data structure mimics the physical layer in both form...
Read more >
ctypes — A foreign function library for Python — Python 3.11.1 ...
It is possible to specify the required argument types of functions exported from DLLs by setting the argtypes attribute. argtypes must be a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found