-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
Processes in Python 3.9 exiting with code 1 when It's created inside a ThreadPoolExecutor #88110
Comments
I've a piece of code that submits a task to a ThreadPoolExecutor which starts a Process. I've realised that in Python 3.8 that Process finished with exit code Here's a minimal example: from multiprocessing import Process
from concurrent.futures import ThreadPoolExecutor
def some_task():
pass
def execute_error():
p = Process(target=some_task)
p.start()
p.join()
print(p.exitcode) # This is always 1 on a ThreadPoolExecutor!!!
executor = ThreadPoolExecutor(max_workers=4)
executor.submit(execute_error)
# execute_error() # IMPORTANT: this works correctly (exit 0) My versions:
Note that if |
Thank you very much for this report, Genaro. I encountered the same bug with a Process running in the context of a Django view. Downgrading to Python 3.8 also fixed the issue for me. Versions: |
I am working on a fix for this bug. I'm a beginner cpython contributor, so if anyone recognizes this as a fool's errand, please let me know! |
Ah never mind. @Genarito, the ThreadPoolExecutor is supposed to be used as a context manager. In your current code, the script ends and Python starts tearing itself down while If you simply use the ThreadPoolExecutor to a context manager, the error goes away:: from multiprocessing import Process
from concurrent.futures import ThreadPoolExecutor
def some_task():
pass
def execute_error():
p = Process(target=some_task)
p.start()
p.join()
print(p.exitcode) # This is always 1 on a ThreadPoolExecutor!!!
# THIS IS THE IMPORTANT CHANGE
with ThreadPoolExecutor(max_workers=4) as executor:
executor.submit(execute_error) |
Hi @jack__d, thanks for your answer and time. Unfortunately, It's still a regression, as in Python < 3.9 my example works as expected |
I've identified the first bad commit with git-bisect: commit b61b818
|
The first bad commit was a fix for bpo-39812. |
the problem is multiprocessing/process is calling threading._shutdown which tries to join its own thread, because concurrent.futures.thread._threads_queues contains the main thread in the subprocess File "/home/graingert/miniconda3/envs/dask-distributed/lib/python3.10/multiprocessing/process.py", line 333, in _bootstrap |
I'm hitting exactly the same issue without |
… 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
And BTW, this applies to Python 3.11 too. I assume 3.10 is also affected. |
… 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
…to avoid joining parent process' threads (GH-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>
… 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>
… 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>
…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>
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: