The following reproducer hangs on a fresh installation of Python 3.11 on Linux.
Traceback (most recent call last):
File "<string>", line 7, in <module>
File "/usr/lib/python3.11/concurrent/futures/_base.py", line 451, in result
self._condition.wait(timeout)
File "/usr/lib/python3.11/threading.py", line 320, in wait
waiter.acquire()
KeyboardInterrupt
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 4, in <module>
File "/usr/lib/python3.11/concurrent/futures/_base.py", line 647, in __exit__
self.shutdown(wait=True)
File "/usr/lib/python3.11/concurrent/futures/process.py", line 825, in shutdown
self._executor_manager_thread.join()
File "/usr/lib/python3.11/threading.py", line 1112, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.11/threading.py", line 1132, in _wait_for_tstate_lock
if lock.acquire(block, timeout):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt
Bug report
Bug description:
Starting in Python 3.11 when the
max_tasks_per_childparameter was introduced,ProcessPoolExecutorhangs whenmax_tasks_per_child>1and enough tasks have been submitted to trigger a worker restart.The following reproducer hangs on a fresh installation of Python 3.11 on Linux.
Issuing a keyboard interrupt results in the following stack trace:
Notes:
result()calls does not help.max_tasks_per_child=1works great. It never hangs, and a new process correctly used for each task.max_tasks_per_childis set high enough so that no worker restarts happen.CPython versions tested on:
3.11, 3.12
Operating systems tested on:
Linux
Linked PRs