Search code examples
c++pythonmultithreadingpython-c-apipython-embedding

Python interpreter as a c++ class


I am working on embedding python in to c++. In some peculiar case I require two separate instances of the interpreter in same thread.

Can I wrap Python interpreter in to a c++ class and get services from two or more class instances?


Solution

  • I have used Py_NewInterpreter for different interpreters in different threads, but this should also work for several interpreters within one thread:

    In the main thread:

    Py_Initialize();
    PyEval_InitThreads();
    mainThreadState = PyEval_SaveThread();
    

    For each interpreter instance (in any thread):

    // initialize interpreter
    PyEval_AcquireLock();                // get the GIL
    myThreadState = Py_NewInterpreter();
    ... // call python code
    PyEval_ReleaseThread(myThreadState); // swap out thread state + release the GIL
    
    ... // any other code
    
    // continue with interpreter
    PyEval_AcquireThread(myThreadState); // get GIL + swap in thread state
    ... // call python code
    PyEval_ReleaseThread(myThreadState);
    
    ... // any other code
    
    // finish with interpreter
    PyEval_AcquireThread(myThreadState);
    ... // call python code
    Py_EndInterpreter(myThreadState);
    PyEval_ReleaseLock();                // release the GIL
    

    Note that you need a variable myThreadState for each interpreter instance!

    Finally the finish in the main thread:

    PyEval_RestoreThread(mainThreadState);
    Py_Finalize();
    

    There are some restrictions with using several interpreter instances (they seem not to be totally independent), but in most cases this does not seem to cause problems.