gh-88110: clear concurrent.futures.thread._threads_queues after fork to avoid joining parent process' threads#126098
Merged
serhiy-storchaka merged 11 commits intopython:mainfrom Nov 22, 2024
Merged
Conversation
… fork
Threads are gone after fork, so clear the queues too. Otherwise the
child process (here created via multiprocessing.Process) crashes on
interpreter exit with:
Traceback (most recent call last):
File "/usr/lib64/python3.11/multiprocessing/popen_fork.py", line 72, in _launch
code = process_obj._bootstrap(parent_sentinel=child_r)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.11/multiprocessing/process.py", line 332, in _bootstrap
threading._shutdown()
File "/usr/lib64/python3.11/threading.py", line 1561, in _shutdown
atexit_call()
File "/usr/lib64/python3.11/concurrent/futures/thread.py", line 31, in _python_exit
t.join()
File "/usr/lib64/python3.11/threading.py", line 1109, in join
raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread
Fixes python#88110
rruuaanng
reviewed
Oct 29, 2024
Misc/NEWS.d/next/Library/2023-02-15-23-54-42.gh-issue-88110.KU6erv.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: RUANG (James Roy) <longjinyii@outlook.com>
Contributor
Author
|
Friendly ping for this review, @rruuaanng Hopefully this one line of code can make it to main :) |
Member
Member
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Please silence the deprecation warning:
test_process_fork_from_a_threadpool (test.test_concurrent_futures.test_thread_pool.ThreadPoolExecutorTest.test_process_fork_from_a_threadpool) ... /home/serhiy/py/cpython-tmp/Lib/multiprocessing/popen_fork.py:67: DeprecationWarning: This process (pid=1243139) is multi-threaded, use of fork() may lead to deadlocks in the child.
self.pid = os.fork()
0.00s ok
rruuaanng
reviewed
Nov 18, 2024
Member
serhiy-storchaka
left a comment
There was a problem hiding this comment.
The test is failing.
Colonel Mustard did it in the Library with the Lead Pipe.
|
Thanks @Drino for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13. |
miss-islington
pushed a commit
to miss-islington/cpython
that referenced
this pull request
Nov 22, 2024
… fork to avoid joining parent process' threads (pythonGH-126098) Threads are gone after fork, so clear the queues too. Otherwise the child process (here created via multiprocessing.Process) crashes on interpreter exit. (cherry picked from commit 1848ce6) Co-authored-by: Andrei Bodrov <Drino@users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
|
GH-127163 is a backport of this pull request to the 3.13 branch. |
miss-islington
pushed a commit
to miss-islington/cpython
that referenced
this pull request
Nov 22, 2024
… fork to avoid joining parent process' threads (pythonGH-126098) Threads are gone after fork, so clear the queues too. Otherwise the child process (here created via multiprocessing.Process) crashes on interpreter exit. (cherry picked from commit 1848ce6) Co-authored-by: Andrei Bodrov <Drino@users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
|
GH-127164 is a backport of this pull request to the 3.12 branch. |
serhiy-storchaka
added a commit
that referenced
this pull request
Nov 22, 2024
…r fork to avoid joining parent process' threads (GH-126098) (GH-127163) Threads are gone after fork, so clear the queues too. Otherwise the child process (here created via multiprocessing.Process) crashes on interpreter exit. (cherry picked from commit 1848ce6) Co-authored-by: Andrei Bodrov <Drino@users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka
added a commit
that referenced
this pull request
Nov 30, 2024
…r fork to avoid joining parent process' threads (GH-126098) (GH-127164) Threads are gone after fork, so clear the queues too. Otherwise the child process (here created via multiprocessing.Process) crashes on interpreter exit. (cherry picked from commit 1848ce6) Co-authored-by: Andrei Bodrov <Drino@users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
ebonnal
pushed a commit
to ebonnal/cpython
that referenced
this pull request
Jan 12, 2025
… fork to avoid joining parent process' threads (pythonGH-126098) Threads are gone after fork, so clear the queues too. Otherwise the child process (here created via multiprocessing.Process) crashes on interpreter exit. Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
12 tasks
yxieca
pushed a commit
to sonic-net/sonic-mgmt
that referenced
this pull request
Feb 11, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com>
nnelluri-cisco
pushed a commit
to nnelluri-cisco/sonic-mgmt
that referenced
this pull request
Feb 12, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com> Signed-off-by: nnelluri-cisco <nnelluri@cisco.com>
anilal-amd
pushed a commit
to anilal-amd/anilal-forked-sonic-mgmt
that referenced
this pull request
Feb 19, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com> Signed-off-by: Zhuohui Tan <zhuohui.tan@amd.com>
mssonicbld
pushed a commit
to mssonicbld/sonic-mgmt
that referenced
this pull request
Feb 25, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com> Signed-off-by: mssonicbld <sonicbld@microsoft.com>
12 tasks
aronovic
pushed a commit
to aronovic/sonic-mgmt
that referenced
this pull request
Mar 3, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com> Signed-off-by: Mihut Aronovici <aronovic@cisco.com>
ravaliyel
pushed a commit
to ravaliyel/sonic-mgmt
that referenced
this pull request
Mar 12, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com> Signed-off-by: Ravali Yeluri (WIPRO LIMITED) <v-ryeluri@microsoft.com>
abhishek-nexthop
pushed a commit
to nexthop-ai/sonic-mgmt
that referenced
this pull request
Mar 17, 2026
What is the motivation for this PR? To fix the ansible worker dead issue observed in sonic-mgmt test. This issue is that the ansible worker is detected dead when calling ansible from thread worker in thread pool. This is same as python/cpython#88110. The root cause is that, concurrent.futures.thread thread pool registers a callback to poll the threads when python interpreter exits, and those thread workers are stored in the dictionary concurrent.futures.thread._threads_queues. The ansible forked child worker process will inherit this dictionary, which contains those orphaned threads. And when the ansible child worker process tries to exit, the callback polls those orphaned threads, causing the worker process returns 1 and ansible complains the worker dead. How did you do it? Backport the cpython fix python/cpython#126098 if the sonic-mgmt python version is < 3.12.8. Signed-off-by: Longxiang Lyu <lolv@microsoft.com> Signed-off-by: Abhishek <abhishek@nexthop.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I've added a test to marmarek@ PR: #101940
_threads_queuesare copied as-is into the fork memory, but there are no threads in the child process, so child process crashes when callingt.join()in_python_exit.I'm facing this issue for the second time during last two years, so I hope it can be fixed :)