When is PyEval_InitThreads meant to be called? [duplicate]
Asked Answered
A

1

5

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?

Applicant answered 17/2, 2013 at 0:38 Comment(1)
Try without the PyEval_ReleaseLock(). The GIL is acquired for a good reason; releasing it before calling other C API functions from Python is going to crash.Isomerous
H
3

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.

Hinshelwood answered 17/2, 2013 at 19:17 Comment(3)
I don't understand this answer. Assuming you are embedding Python in a C program, and you have 20 worker threads, who should call PyEval_InitThreads, and how does each worker release the lock while it's off doing other things so other threads that need to do some Python work can get the GIL?Legislate
@DougN, yeah I agree. The answer is vague (as are the Python docs themselves unfortunately)Unreliable
If you are embedding Python i a C program, call it once for the entire program as you initialize your embedded Python interpreter before having it execute your first Python code.Hinshelwood

© 2022 - 2024 — McMap. All rights reserved.