You have a program that involves a mix of C, Python, and threads, but some of thethreads are created from C outside the control of the Python interpreter. Moreover,certain threads utilize functions in the Python C API.
If you’re going to mix C, Python, and threads together, you need to make sure youproperly initialize and manage Python’s global interpreter lock (GIL). To do this, includethe following code somewhere in your C code and make sure it’s called prior to creationof any threads:
...if (!PyEval_ThreadsInitialized()) {
PyEval_InitThreads();
For any C code that involves Python objects or the Python C API, make sure you prop‐erly acquire and release the GIL first. This is done using PyGILState_Ensure() andPyGILState_Release(), as shown in the following:
.../ Make sure we own the GIL [](#)/PyGILState_STATE state = PyGILState_Ensure();
/ Use functions in the interpreter /.../ Restore previous GIL state and return [](#)/PyGILState_Release(state);...
Every call to PyGILState_Ensure() must have a matching call to PyGILState_Release().
In advanced applications involving C and Python, it is not uncommon to have manythings going on at once—possibly involving a mix of a C code, Python code, C threads,and Python threads. As long as you diligently make sure the interpreter is properlyinitialized and that C code involving the interpreter has the proper GIL managementcalls, it all should work.Be aware that the PyGILState_Ensure() call does not immediately preempt or interruptthe interpreter. If other code is currently executing, this function will block until thatcode decides to release the GIL. Internally, the interpreter performs periodic threadswitching, so even if another thread is executing, the caller will eventually get to run(although it may have to wait for a while first).