Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #83320 > unrolled thread

Re: PyGILState API and Py_Main

Started bydieter <dieter@handshake.de>
First post2015-01-08 08:22 +0100
Last post2015-01-08 08:22 +0100
Articles 1 — 1 participant

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: PyGILState API and Py_Main dieter <dieter@handshake.de> - 2015-01-08 08:22 +0100

#83320 — Re: PyGILState API and Py_Main

Fromdieter <dieter@handshake.de>
Date2015-01-08 08:22 +0100
SubjectRe: PyGILState API and Py_Main
Message-ID<mailman.17466.1420701874.18130.python-list@python.org>
Adrien Bruneton <adrien.bruneton@cea.fr> writes:

> I am having a hard time understanding what is the proper use of
> PyGILState_Ensure/Release.
> My understanding is that one should always be matched with the other,
> and that this high level API auto-magically deals with the ThreadState
> creation.
>
> However the following piece of code (executed with a simple "print
> 'hello world' " script as argv) triggers the message:
>
>     Fatal Python error: auto-releasing thread-state, but no
> thread-state for this thread

Each function at the Python C interface has (with high probability)
a notion whether it is called from Python (GIL acquired) or from pure C code
(GIL not acquired). When you call the function yourself, you must match
this expectation. "Py_Main" likely expects to be called without
acquired GIL. Thus, likely, you should not call "PyGILState_Ensure"
before "Py_Main".

> Minimal code:
>
> void initPython(int initsigs)
> {
>   if (Py_IsInitialized() == 0)
>     {
>       Py_InitializeEx(initsigs);
>       // Put default SIGINT handler back after
> Py_Initialize/Py_InitializeEx.
>       signal(SIGINT, SIG_DFL);
>     }
>
>   int threadInit = PyEval_ThreadsInitialized();
>   PyEval_InitThreads(); // safe to call this multiple time
>
>   if(!threadInit)
>     PyEval_SaveThread(); // release GIL
> }
>
> int main(int argc, char ** argv)
> {
>   initPython(1);
>   PyGILState_STATE _gstate_avoid_clash = PyGILState_Ensure();
>   int ret = Py_Main(argc, argv);
>   PyGILState_Release(_gstate_avoid_clash);  // this one triggers the
> Fatal error
>   Py_Finalize();
>   return ret;
> }
>
>
> Removing the last PyGILState_Release works, but I have a bad feeling
> about it :-)
> Any help would be welcome! Thanks in advance.

Likely, "Py_Main" has already released the GIL and cleaned up
the thread state.

[toc] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web