-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
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
RLock undocumented behavior in case of multiple acquire #70795
Comments
The number of acquisitions must be the same as the number of releases or else lock will not be released for other threads leading to deadlock. This is not mentioned in documentation. First acquisition returns boolean and further acquisitions return 1. This is also not mentioned in documentation. |
Per the docs ( https://docs.python.org/3/library/threading.html#rlock-objects ): "To unlock the lock, a thread calls its release() method. acquire()/release() call pairs may be nested; only the final release() (the release() of the outermost pair) resets the lock to unlocked and allows another thread blocked in acquire() to proceed." The docs aren't super clear on the return type, but they aren't so overly specified as to make returning either True or 1 incorrect; they use lowercase "true" to describe the return value, which doesn't *have* to mean True, just something that evaluates as truthy. In 3.5 at least, it looks like both initial and subsequent acquires are all returning True, even when called without passing an argument; this actually violates the docs, which claim that not passing an argument means "There is no return value" (possibly only when there is contended acquisition, the wording is odd), when in fact a no-argument call returns True just like explicitly passing blocking as True. |
As seen from commit log, all return type are double back-quoted, this could be a rendering error. I think this commit somehow makes it clear that RLock is a thread-level reentrant lock, some code example of suggested usage might be helpful though. |
The RLock documentation is a bit more verbose than it needs to be (for instance, there is no reason to specify the "no args" case separately from the "blocking=True" case (since True is the default value of blocking). The issue of balancing acquire/release calls is mentioned as Josh says, but could perhaps be stated more simply as well. |
Working on this at PyCon 2023's cpython sprint. |
Notes while trying to update the documentation:
This longer seems to be true; acquire appears to always return
I have no idea what this means; why would it not return True or False? Confirmed w/ @gpshead it doesn't make sense. It's able to acquire the lock or not! Here's a test program I have been fiddling with on Python 3.12: import operator
import time
import threading
LEVEL_LIMIT: int = 10
THREADS_MAX = 16
global_rlock = threading.RLock()
def recursively_lock(level: int):
"""Test for RLock. Recusively call itself and observe the return value of acquire/release."""
tid = threading.get_ident()
if level == LEVEL_LIMIT:
print(f"{LEVEL_LIMIT=} reached, stopping recursion")
return
print(f"Started {tid=}")
rv = global_rlock.acquire(blocking=False)
if rv:
print(f"RLock acquire()={rv} at {level=} for {tid=}")
time.sleep(0.1)
recursively_lock(level + 1)
rv = global_rlock.release()
print(f"RLock release()={rv} at {level=}")
else:
print(f"Unable to acquire lock for {tid=} {rv=}")
if __name__ == "__main__":
threads: list[threading.Thread] = []
for i in range(0, THREADS_MAX):
threads.append(threading.Thread(target=recursively_lock, args=(0,)))
for t in threads:
t.start()
# map(operator.methodcaller("start"), threads)
map(operator.methodcaller("join"), threads)
print("Hello world") I've been unable to replicate the case where None is returned, or acquire not returning True or False. |
Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta).
The old docs mention that Double checked by gpshead |
Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta). Add a seealso for with-locks. Switch section to use bullet points. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta). Add a seealso for with-locks. Switch section to use bullet points. --------- (cherry picked from commit 2fbea81) Co-authored-by: uıɐɾ ʞ ʇɐɯɐs <_@skj.io> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta). Add a seealso for with-locks. Switch section to use bullet points. --------- (cherry picked from commit 2fbea81) Co-authored-by: uıɐɾ ʞ ʇɐɯɐs <_@skj.io> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
gh-70795: Rework RLock documentation (GH-103853) Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta). Add a seealso for with-locks. Switch section to use bullet points. --------- (cherry picked from commit 2fbea81) Co-authored-by: uıɐɾ ʞ ʇɐɯɐs <_@skj.io> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
gh-70795: Rework RLock documentation (GH-103853) Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta). Add a seealso for with-locks. Switch section to use bullet points. --------- (cherry picked from commit 2fbea81) Co-authored-by: uıɐɾ ʞ ʇɐɯɐs <_@skj.io> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
Attempted to simultaneously reduce verbosity, while more descriptively describing behavior. Fix links (RLock acquire/release previously linking to Lock acquire/release, seems like bad copy pasta). Add a seealso for with-locks. Switch section to use bullet points. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
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:
Linked PRs
The text was updated successfully, but these errors were encountered: