Multithreaded C API Python questions

Svein Seldal svein at seldal dot com
Tue Nov 14 07:54:33 EST 2006


Hi!

I think I've found the bug, but I need to confirm this behavior.

My findings is that if you use PyEval_InitThreads(), it is crucial to 
release the GIL with PyEval_ReleaseThread() afterwards.

The API docs states that you can release the GIL with 
PyEval_ReleaseLock() or PyEval_ReleaseThread() AFAICS. 
http://docs.python.org/api/threads.html under docs of void 
PyEval_InitThreads().

However, if I do use PyEval_ReleaseLock() it will crash shortly after 
with "Fatal Python error: ceval: tstate mix-up" in a multithreaded C 
environment.

If I use PyEval_ReleaseThread() to release the GIL, my app seems stable. 
I release the GIL like this:

     PyThreadState *pts = PyGILState_GetThisThreadState();
     PyEval_ReleaseThread(pts);

Now, is this a feature or expected behavior in python (i.e. unclear API 
documentation), or is this a bug in python itself?


Regards,
Svein


PS:

For reference I did something like this in pseudo-code:

     Py_Initialize();
     PyEval_InitThreads();

     other_py_inits();   // Load py modules, etc.

     PyEval_ReleaseLock();    // <-- MAKES THE APP UNSTABLE

     create_c_thread();

     PyGILState_STATE gstate;
     gstate = PyGILState_Ensure();

     call_py_function_main();  // Py main() wont return

     PyGILState_Release(gstate);


And the "main" of the C thread function looks like this:
    while(1)
    {
         PyGILState_STATE gstate;
         gstate = PyGILState_Ensure();

         call_py_function_send();

         PyGILState_Release(gstate);
    }



More information about the Python-list mailing list