-
-
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
_thread.lock.release()
is not thread-safe in free-threaded builds
#117721
Comments
Hi, I am currently working on implementing part of the OpenMP API in native Python, and I need to be able to prevent concurrent updates to shared variables (If you are familiar with OpenMP, implementing the Note that this is custom syntax I'm introducing with my library, I'm giving this extract to give an idea of what I'm talking about. Here is the example I would like to run. @omp.enable
def main():
acc = 0
with OpenMP("parallel"):
with OpenMP("for"):
for i in range(1000):
with OpenMP("critical"):
acc += i
print(acc) # Actual output
print(sum(range(1000))) # Expected output I decided to use a threading.Lock instance to protect the region, however it seems like there are concurrent accesses despite the protection. I keep getting results that are different from what I get with the GIL, or a deadlock. An example of output I get in python3.14t
But really most of the time I get a deadlock when all I'm doing is using a shared threading.Lock instance in a context manager to protect the Is there any way to protect shared variables from concurrent accesses in user code written in pure Python?
I didn't check the details of the race conditions in the implementation _thread.lock, but I imagine from what you say that the behaviour I'm facing is highlighted by the fact the region I'm trying to protect is a single instruction. In any case, Thanks, |
It sounds like you have some other bug in your code. The issue described by Matt is only relevant about the errors raised when trying to unlock a lock that is already unlocked (i.e., an error raised when misusing the lock) |
Thank you for the clarification, I am using a context manager so I don't think I would be unlocking an already unlocked lock. Sorry to have bothered you, have a great day! Thanks, |
(cherry picked from commit fca5529)
Bug report
Bug description:
The implementation of
_thread.lock.release()
manipulates thelocked
field in a thread-unsafe way (this may be called by a thread that does not hold the lock) in free-threaded builds:cpython/Modules/_threadmodule.c
Lines 813 to 825 in 630df37
We're choosing to punt on this for 3.13 since this should only be problematic for contended unlocks. We can revisit this for 3.13 if it turns out to be an issue in practice.
Post 3.13 we would like to change the underlying lock to be a
PyMutex
and replace the implementation with something like:CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
_thread.lock
#125110_thread.lock
(#125110) #125116The text was updated successfully, but these errors were encountered: