You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2011-02-28.14:48:10.103>created_at=<Date2007-05-16.19:46:29.000>labels= ['type-feature', 'docs']
title='PyGILState_Ensure does not acquires GIL'updated_at=<Date2011-02-28.14:48:10.102>user='https://bugs.python.org/kunoospald'
The function PyGILState_Ensure doesn't acquire the GIL if current thread state is valid. In contrast to that PyGILState_Release deletes the thread state (PyThreadState_DeleteCurrent) which releases the GIL which got not acquired before (=> mutex->owned = -2).
Here is an example which locks at PyRun_SimpleString:
// initialize the Python interpreterPy_Initialize();
PyEval_InitThreads();
// release the GIL as PyEval_InitThreads // implicitly acquires the GILPyEval_ReleaseLock();
In that simple example the problem can be fixed by removing the call to PyEval_ReleaseLock. But that is needed for applications that call into the interpreter from multiple threads.
The only solution I could found up to that point is the following:
// initialize the Python interpreterPy_Initialize();
PyEval_InitThreads();
PyThreadState* tcur = PyThreadState_Get() ;
PyThreadState_Swap(NULL);
PyThreadState_Clear(tcur);
PyThreadState_Delete(tcur);
// release the GIL as PyEval_InitThreads // implicitly acquires the GILPyEval_ReleaseLock();
In my embedding, I use the following (adapting the example above):
// initialize the Python interpreterPy_Initialize();
PyEval_InitThreads();
/* Swap out and return current thread state and release the GIL */PyThreadStatetstate=PyEval_SaveThread();
You don't have to free the tstate returned by PyEval_SaveThread because
it is the thread state of the main thread (as established during
Py_Initialize), and so it will be freed during Python's shut-down.
I think in general you should rarely need to call PyEval_ReleaseLock
directly; instead use PyEval_SaveThread, the Py_BEGIN_ALLOW_THREADS
macro, or PyGILState_Release (as appropriate). The documentation should
probably say as much.
This is still the case: the documentation should mention that PyEval_ReleaseLock() is not the correct function to release "the GIL", both the interpreter lock *and* the current thread state have to be released.
Activity
kunoospald commentedon May 16, 2007
The function PyGILState_Ensure doesn't acquire the GIL if current thread state is valid. In contrast to that PyGILState_Release deletes the thread state (PyThreadState_DeleteCurrent) which releases the GIL which got not acquired before (=> mutex->owned = -2).
Here is an example which locks at PyRun_SimpleString:
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
In that simple example the problem can be fixed by removing the call to PyEval_ReleaseLock. But that is needed for applications that call into the interpreter from multiple threads.
The only solution I could found up to that point is the following:
PyThreadState* tcur = PyThreadState_Get() ;
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
Which seems to works fine. But I think that this behavior of PyGILState_Ensure should be either documented or fixed.
Thanks,
Kuno
glchapman21 commentedon Nov 18, 2007
In my embedding, I use the following (adapting the example above):
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
You don't have to free the tstate returned by PyEval_SaveThread because
it is the thread state of the main thread (as established during
Py_Initialize), and so it will be freed during Python's shut-down.
I think in general you should rarely need to call PyEval_ReleaseLock
directly; instead use PyEval_SaveThread, the Py_BEGIN_ALLOW_THREADS
macro, or PyGILState_Release (as appropriate). The documentation should
probably say as much.
terryjreedy commentedon Jul 10, 2010
Please check whether this is still an issue in 3.1, so that there is still an issue for 3.2.
amauryfa commentedon Jul 10, 2010
This is still the case: the documentation should mention that PyEval_ReleaseLock() is not the correct function to release "the GIL", both the interpreter lock *and* the current thread state have to be released.
pitrou commentedon Jul 10, 2010
I'm not even sure what PyEval_AcquireLock() and PyEval_ReleaseLock() are good for. Perhaps they should be deprecated.
ncoghlan commentedon Feb 28, 2011
Given the deprecation of PyEval_ReleaseLock in bpo-10913, should this be closed as "out of date"?
pitrou commentedon Feb 28, 2011
Indeed :)