I'm trying to understand sub-interpreters and GIL. But my experiment is failing often(The same code rarely works).
Gathering info from SO questions and few sites, I have the following code which spawns 2 non-python threads. Each of these threads are given a python sub-interpreter. I want to release GIL inside these threads and call a DLL function in C++(though this example does not detail that. Here I just write to stdout). Basically I want to see concurrency in the execution(Non-Python DLL invocation).
#include <iostream>
#include <thread>
#include <Python.h>
void worker(PyInterpreterState* interp, int n) 
{
    PyThreadState* ts;
    ts = PyThreadState_New(interp);
    PyThreadState_Swap(ts);
    PyThreadState* _save;
    _save = PyEval_SaveThread();
    std::cout << n << std::endl;  // Non-Python execution. My Focus.
    PyEval_RestoreThread(_save);
    PyThreadState_Swap(ts);
    PyThreadState_Clear(ts);
    PyThreadState_DeleteCurrent();
    return;
}
int main()
{
    try 
    {
        Py_Initialize();
        PyEval_InitThreads();
        PyThreadState* _main = PyThreadState_Get();
        PyThreadState* i1 = Py_NewInterpreter();
        PyThreadState* i2 = Py_NewInterpreter();
        std::thread t1(worker, i1->interp, 1);
        std::thread t2(worker, i2->interp, 2);
        t1.join();
        t2.join();
        PyThreadState_Swap(i1);
        PyThreadState_Clear(i1);
        Py_EndInterpreter(i1);
        PyThreadState_Swap(i2);
        PyThreadState_Clear(i2);
        Py_EndInterpreter(i2);
        PyThreadState_Swap(_main);
        Py_Finalize();
        return 0;
    }
    catch(std::exception& e)
    {
        std::cout << "Exception:" << std::endl << e.what() << std::endl;
    }
}
Running a single thread works all the time. When I run 2 threads as shown, I get any of the following outputs.
- In PyEval_SaveThread(),
2
Fatal Python error: drop_gil: GIL is not locked
Python runtime state: initialized
Current thread 0x00002d08 (most recent call first):
<no Python frame>
- In PyEval_SaveThread(),
1
Fatal Python error: PyEval_SaveThread: NULL tstate
Python runtime state: initialized
Current thread 0x00003eb8 (most recent call first):
<no Python frame>
Either of the thread succeeds, the other one fails.
- Rarely works. The same code.
1
2
Can someone shed some light on this? Need help. Thanks.
 
    