Re: Right way to initialize python embedded in a multi-threaded application

2013-05-11 Thread francis . brosnan
Hi,

Maybe you already fixed the issue, but for the record, I've got the same
problem and finally it turned out that I was calling PyEval_InitThreads twice
and also after fixing that, I also had to move the call to 
PyEval_ReleaseLock();  at the end of the entire initialization (not just after 
PyEval_initThreads).

The key thing there is to follow:

at initialization thread
Py_Initialize ();
PyEval_InitThreads(); 
/* now call here to initialize all python code by loading external files 
   or internal module loading (i.e. Py_InitModule3) */
/* ..and now, once no more Python C/API call is required, release
   the GIL so other threads can come into play */
PyEval_ReleaseLock ();

and now, from other threads, use
/* wait til gil acquired */
state  = PyGILState_Ensure();
/* your code */
/* release GIL */
PyGILState_Release (state);

Hope it helps, Cheers!


 I'm embedding python in a multi-threaded C application.
 
 I've taken care to wrap every call to the Python C API with
 
 
 
 gstate = PyGILState_Ensure();
 
 // call python code
 
 PyGILState_Release(gstate);
 
 
 
 But I'm stumped with what to do in the initialization.
 
 Right after the call to Py_IsInitialized() I've added a call:
 
 
 
 PyEval_InitThreads();
 
 
 
 The docs say that this function leaves the GIL locked when it returns.
 
 I do some more initializations like importing modules and then I call
 
 
 
 PyEval_ReleaseLock();
 
 
 
 This seems to cause a problem since not long after a call to
 
 PyGILState_Release(gstate) that's made in a different thread crashes.
 
 with
 
 
 
 Fatal Python error: This thread state must be current when releasing
 
 
 
 If I don't do the call to PyEval_ReleaseLock() in the main thread
 
 right after initialization, the GIL seems to be released
 
 after the first PyGILState_Ensure() - PyGILState_Release() pair.
 
 
 
 So what am I doing wrong here?
 
 What is the correct way of initializing a multi-threaded application?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Right way to initialize python embedded in a multi-threaded application

2013-05-11 Thread francis . brosnan
Just clarify there's no problem about calling twice to PyEval_InitThreads ()
as indicated by Python's doc.

 Hi,
 
 
 
 Maybe you already fixed the issue, but for the record, I've got the same
 
 problem and finally it turned out that I was calling PyEval_InitThreads twice
 
 and also after fixing that, I also had to move the call to 
 PyEval_ReleaseLock();  at the end of the entire initialization (not just 
 after PyEval_initThreads).
 
 
 
 The key thing there is to follow:
 
 
 
 at initialization thread
 
 Py_Initialize ();
 
 PyEval_InitThreads(); 
 
 /* now call here to initialize all python code by loading external files 
 
or internal module loading (i.e. Py_InitModule3) */
 
 /* ..and now, once no more Python C/API call is required, release
 
the GIL so other threads can come into play */
 
 PyEval_ReleaseLock ();
 
 
 
 and now, from other threads, use
 
 /* wait til gil acquired */
 
 state  = PyGILState_Ensure();
 
 /* your code */
 
 /* release GIL */
 
 PyGILState_Release (state);
 
 
 
 Hope it helps, Cheers!
 
 
 
 
 
  I'm embedding python in a multi-threaded C application.
 
  
 
  I've taken care to wrap every call to the Python C API with
 
  
 
  
 
  
 
  gstate = PyGILState_Ensure();
 
  
 
  // call python code
 
  
 
  PyGILState_Release(gstate);
 
  
 
  
 
  
 
  But I'm stumped with what to do in the initialization.
 
  
 
  Right after the call to Py_IsInitialized() I've added a call:
 
  
 
  
 
  
 
  PyEval_InitThreads();
 
  
 
  
 
  
 
  The docs say that this function leaves the GIL locked when it returns.
 
  
 
  I do some more initializations like importing modules and then I call
 
  
 
  
 
  
 
  PyEval_ReleaseLock();
 
  
 
  
 
  
 
  This seems to cause a problem since not long after a call to
 
  
 
  PyGILState_Release(gstate) that's made in a different thread crashes.
 
  
 
  with
 
  
 
  
 
  
 
  Fatal Python error: This thread state must be current when releasing
 
  
 
  
 
  
 
  If I don't do the call to PyEval_ReleaseLock() in the main thread
 
  
 
  right after initialization, the GIL seems to be released
 
  
 
  after the first PyGILState_Ensure() - PyGILState_Release() pair.
 
  
 
  
 
  
 
  So what am I doing wrong here?
 
  
 
  What is the correct way of initializing a multi-threaded application?
-- 
http://mail.python.org/mailman/listinfo/python-list


Right way to initialize python embedded in a multi-threaded application

2012-05-17 Thread shooshx
I'm embedding python in a multi-threaded C application.
I've taken care to wrap every call to the Python C API with

gstate = PyGILState_Ensure();
// call python code
PyGILState_Release(gstate);

But I'm stumped with what to do in the initialization.
Right after the call to Py_IsInitialized() I've added a call:

PyEval_InitThreads();

The docs say that this function leaves the GIL locked when it returns.
I do some more initializations like importing modules and then I call

PyEval_ReleaseLock();

This seems to cause a problem since not long after a call to
PyGILState_Release(gstate) that's made in a different thread crashes.
with

Fatal Python error: This thread state must be current when releasing

If I don't do the call to PyEval_ReleaseLock() in the main thread
right after initialization, the GIL seems to be released
after the first PyGILState_Ensure() - PyGILState_Release() pair.

So what am I doing wrong here?
What is the correct way of initializing a multi-threaded application?


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Right way to initialize python embedded in a multi-threaded application

2012-05-17 Thread Mark Hammond

On 17/05/2012 10:08 PM, shooshx wrote:

I'm embedding python in a multi-threaded C application.
I've taken care to wrap every call to the Python C API with

gstate = PyGILState_Ensure();
// call python code
PyGILState_Release(gstate);

But I'm stumped with what to do in the initialization.
Right after the call to Py_IsInitialized() I've added a call:

PyEval_InitThreads();

The docs say that this function leaves the GIL locked when it returns.
I do some more initializations like importing modules and then I call

PyEval_ReleaseLock();

This seems to cause a problem since not long after a call to
PyGILState_Release(gstate) that's made in a different thread crashes.
with

Fatal Python error: This thread state must be current when releasing

If I don't do the call to PyEval_ReleaseLock() in the main thread
right after initialization, the GIL seems to be released
after the first PyGILState_Ensure() - PyGILState_Release() pair.

So what am I doing wrong here?
What is the correct way of initializing a multi-threaded application?


Try replacing the PyEval_ReleaseLock() call with PyEval_SaveThread(); - 
that works for pythoncom, which has the same basic requirement - see 
http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/raw-file/b8c62cf04c5a/com/win32com/src/dllmain.cpp 
for how it works.


HTH,

Mark






--
http://mail.python.org/mailman/listinfo/python-list