-
-
Notifications
You must be signed in to change notification settings - Fork 30.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PyGILState_Ensure does not acquires GIL #44960
Comments
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 interpreter
Py_Initialize();
PyEval_InitThreads();
// release the GIL as PyEval_InitThreads
// implicitly acquires the GIL
PyEval_ReleaseLock(); PyGILState_STATE gstate; PyRun_SimpleString("import random\n");
PyGILState_Release(gstate); 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 interpreter
Py_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 GIL
PyEval_ReleaseLock(); PyGILState_STATE gstate; PyRun_SimpleString("import random\n");
PyGILState_Release(gstate); Which seems to works fine. But I think that this behavior of PyGILState_Ensure should be either documented or fixed. Thanks, |
In my embedding, I use the following (adapting the example above): // initialize the Python interpreter
Py_Initialize();
PyEval_InitThreads();
/* Swap out and return current thread state and release the GIL */
PyThreadState tstate = PyEval_SaveThread(); PyGILState_STATE gstate; PyRun_SimpleString("import random\n");
PyGILState_Release(gstate); You don't have to free the tstate returned by PyEval_SaveThread because I think in general you should rarely need to call PyEval_ReleaseLock |
Please check whether this is still an issue in 3.1, so that there is still an issue for 3.2. |
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. |
I'm not even sure what PyEval_AcquireLock() and PyEval_ReleaseLock() are good for. Perhaps they should be deprecated. |
Given the deprecation of PyEval_ReleaseLock in bpo-10913, should this be closed as "out of date"? |
Indeed :) |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: