-
-
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
fix for bpo-36402 (threading._shutdown() race condition) causes reference leak #81969
Comments
Starting with commit 468e5fe (bpo-36402: Fix threading._shutdown() race condition (GH-13948)) the following trivial test case leaks one reference and one memory block. class MiscTestCase(unittest.TestCase):
def test_without_join(self):
# Test that a thread without join does not leak references.
# Use a debug build and run "python -m test -R: test_threading"
threading.Thread().start() Attached is a patch, that adds this test case to Lib/test/test_threading.py. After you apply this patch "python -m test -R: test_threading" leaks one (additional) reference. This leak is also present in Python 3.7.4 and 3.8. I'm not sure, if it correct not to join a thread, but it did work flawlessly and didn't leak in previous releases. |
The root cause for the reference leak is the global set threading._shutdown_locks. It contains Thread._tstate_lock locks of non-daemon threads. If a non-daemon thread terminates and no other thread joins the terminated thread, the _tstate_lock remains in threading._shutdown_locks forever. I could imagine that a long running server could accumulate many locks in threading._shutdown_locks over time. Therefore the leak should be fixed. There are probably several ways to deal with this issue. A straight forward approach is to discard the lock from within |
This change introduced a regression :-( I created PR 15338 to revert it |
Copy of wmanley's comment: |
Hummm....is this really a regression? The docs say:
So if someone is overriding join() they are out of contract |
I ran into this bug as well, and opened an issue for it (before I saw this issue): https://bugs.python.org/issue39074 Was there a conclusion on the best way to fix this? It seems like the previous __del__ implementation would correct the resource leakage by removing the _tstate_lock from _shutdown_locks. |
I marked bpo-39074 as a duplicate of this issue. |
I marked bpo-39201 as a duplicate of this issue. |
I have reproduced a similar memory leak in the multiprocessing This is the trace: 913 memory blocks: 33232 Bytes: File "/usr/lib/python3.7/threading.py", line 890; self._bootstrap_inner(); File "/usr/lib/python3.7/threading.py", line 914; self._set_tstate_lock(); File "/usr/lib/python3.7/threading.py", line 904; self._tstate_lock = _set_sentinel(); |
I marked bpo-42263 as a duplicate of this issue. This issue is implicated in preventing the desired fix for bpo-37193, where a thread wishes to remove the handle to itself after performing its duty. By removing its own handle, it can never be joined, and thus obviates the most straightforward way to directly remove the handle for a thread within that thread. |
bpo-37193 has been fixed. |
Re-opening; I believe this issue is still valid. Here's output on a debug build on current master (commit 7591d94) on my machine: lovelace:cpython mdickinson$ ./python.exe
Python 3.10.0a6+ (remotes/upstream/master:7591d9455e, Mar 13 2021, 12:04:31) [Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, threading, time
>>> for _ in range(10):
... threading.Thread().start()
... time.sleep(0.1)
... print(sys.gettotalrefcount())
...
109901
109905
109907
109909
109911
109913
109915
109917
109919
109921 |
Oh, I'm confused. This issue is about the threading module, whereas bpo-37193 is unrelated: it's about the socketserver module. |
ping I also encountered this problem. Is there a fix now? |
No. The issue remains open. |
Anselm's pull request PR 15175 looked hopeful to me. I've been using those changes in our builds at work for a while. |
Fix in the main branch: commit c10c2ec
|
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: