When is PyEval_InitThreads meant to be called? [du

2019-04-08 20:33发布

问题:

This question already has an answer here:

  • PyEval_InitThreads in Python 3: How/when to call it? (the saga continues ad nauseam) 7 answers

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?

回答1:

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.