[3.12] gh-114440: Close writer pipe in multiprocessing.Queue, not concurrent.futures (GH-114489)

This was left out of the 3.12 backport for three related issues:
- gh-107219 (which adds `self.call_queue._writer.close()` to `_ExecutorManagerThread` in `concurrent.futures`)
- gh-109370 (which changes this to be only called on Windows)
- gh-109047 (which moves the call to `multiprocessing.Queue`'s `_terminate_broken`)

Without this change, ProcessPoolExecutor sometimes hangs on Windows
when a worker process is terminated.

Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Petr Viktorin 2024-01-24 13:21:10 +01:00 committed by GitHub
parent 03f8f77885
commit c912bc3ed4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 11 additions and 5 deletions

View file

@ -524,11 +524,6 @@ class _ExecutorManagerThread(threading.Thread):
self.call_queue._terminate_broken()
# gh-107219: Close the connection writer which can unblock
# Queue._feed() if it was stuck in send_bytes().
if sys.platform == 'win32':
self.call_queue._writer.close()
# clean up resources
self._join_executor_internals(broken=True)

View file

@ -164,6 +164,11 @@ class Queue(object):
# gh-94777: Prevent queue writing to a pipe which is no longer read.
self._reader.close()
# gh-107219: Close the connection writer which can unblock
# Queue._feed() if it was stuck in send_bytes().
if sys.platform == 'win32':
self._writer.close()
self.close()
self.join_thread()

View file

@ -0,0 +1,6 @@
On Windows, closing the connection writer when cleaning up a broken
:class:`multiprocessing.Queue` queue is now done for all queues, rather than
only in :mod:`concurrent.futures` manager thread.
This can prevent a deadlock when a ``multiprocessing`` worker process terminates
without cleaning up.
This completes the backport of patches by Victor Stinner and Serhiy Storchaka.