You're encountering a hang because Python’s Global Interpreter Lock (GIL) is not correctly managed in a multithreaded context. When Py_Initialize()
is called, the main thread holds the GIL by default. However, if you later call PyGILState_Ensure()
from other threads (like Taskflow tasks) without releasing the GIL in the main thread first, you cause a deadlock — the other threads block forever waiting for the GIL.
After Py_Initialize()
, immediately release the GIL using PyEval_SaveThread()
before spawning threads:
Py_Initialize();
PyEval_InitThreads(); // deprecated in Python 3.9+, but harmless
PyThreadState* tstate = PyEval_SaveThread(); // releases GIL
Then in each task/thread that wants to run Python code:
PyGILState_STATE gil = PyGILState_Ensure();
// ... run Python code
PyGILState_Release(gil);
Finally, before Py_FinalizeEx()
, restore the GIL to the main thread:
PyEval_RestoreThread(tstate);
Py_FinalizeEx();
Notes:
Never call Python APIs from threads without ensuring the GIL.
Python 3.9+ automatically initializes threading, so PyEval_InitThreads()
is legacy-safe.
Always balance PyGILState_Ensure()
with PyGILState_Release()
.
Regards