Embedding python in multithreaded C application

I had exactly the same problem and it is now solved by using PyEval_SaveThread() immediately after PyEval_InitThreads(), as you suggest above. However, my actual problem was that I used PyEval_InitThreads() after PyInitialise() which then caused PyGILState_Ensure() to block when called from different, subsequent native threads. In summary, this is what I do now:

  1. There is global variable:

    static int gil_init = 0; 
  2. From a main thread load the native C extension and start the Python interpreter:

  3. From multiple other threads my app concurrently makes a lot of calls into the Python/C API:

    if (!gil_init) {
        gil_init = 1;
    state = PyGILState_Ensure();
    // Call Python/C API functions...    
  4. From the main thread stop the Python interpreter


All other solutions I’ve tried either caused random Python sigfaults or deadlock/blocking using PyGILState_Ensure().

The Python documentation really should be more clear on this and at least provide an example for both the embedding and extension use cases.

Leave a Comment