I'm a bit confused about when I'm supposed to call PyEval_InitThreads
. In general, I understand that PyEval_InitThreads
must be called whenever a non-Python thread (i.e. a thread that is spawned within an extension module) is used.
However, I'm confused if PyEval_InitThreads
is for C programs which embed the Python interpreter, or Python programs which import C-extension modules, or both.
So, if I write a C extension module that will internally launch a thread, do I need to call PyEval_InitThreads
when initializing the module?
Also, PyEval_InitThreads
implicitly acquires the Global Interpreter Lock. So after calling PyEval_InitThreads
, presumably the GIL must be released or deadlock will ensue. So how do you release the lock? After reading the documentation, PyEval_ReleaseLock()
appears to be the way to release the GIL. However, in practice, if I use the following code in a C extension module:
PyEval_InitThreads();
PyEval_ReleaseLock();
...then at runtime Python aborts with:
Fatal Python error: drop_gil: GIL is not locked
So how do you release the GIL after acquiring it with PyEval_InitThreads
?
Most applications never need to know about PyEval_InitThreads()
at all.
The only time you should use it is if your embedding application or extension module will be making Python C API calls from more than one thread that it spawned itself outside of Python.
Don't call PyEval_ReleaseLock()
in any thread which will later be making Python C API calls (unless you re-acquire it before those). In that case you should really use the Py_BEGIN_ALLOW_THREADS
and Py_END_ALLOW_THREADS
macros instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With