Skip to content

Commit

Permalink
pythongh-94777: Fix deadlock in ProcessPoolExecutor (pythonGH-94784)
Browse files Browse the repository at this point in the history
Fixes a hang in multiprocessing process pool executor when a child process crashes and code could otherwise block on writing to the pipe.  See pythonGH-94777 for more details.
(cherry picked from commit 6782fc0)

Co-authored-by: Louis Paulot <55740424+lpaulot@users.noreply.github.com>
  • Loading branch information
lpaulot authored and miss-islington committed Jul 10, 2023
1 parent 563829d commit fc537a3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Lib/concurrent/futures/process.py
Expand Up @@ -497,6 +497,10 @@ def terminate_broken(self, cause):
for p in self.processes.values():
p.terminate()

# Prevent queue writing to a pipe which is no longer read.
# https://github.com/python/cpython/issues/94777
self.call_queue._reader.close()

# clean up resources
self.join_executor_internals()

Expand Down
18 changes: 18 additions & 0 deletions Lib/test/test_concurrent_futures.py
Expand Up @@ -1167,6 +1167,11 @@ def _crash(delay=None):
faulthandler._sigsegv()


def _crash_with_data(data):
"""Induces a segfault with dummy data in input."""
_crash()


def _exit():
"""Induces a sys exit with exitcode 1."""
sys.exit(1)
Expand Down Expand Up @@ -1366,6 +1371,19 @@ def test_shutdown_deadlock_pickle(self):
# dangling threads
executor_manager.join()

def test_crash_big_data(self):
# Test that there is a clean exception instad of a deadlock when a
# child process crashes while some data is being written into the
# queue.
# https://github.com/python/cpython/issues/94777
self.executor.shutdown(wait=True)
data = "a" * support.PIPE_MAX_SIZE
with self.executor_type(max_workers=2,
mp_context=self.get_context()) as executor:
self.executor = executor # Allow clean up in fail_on_deadlock
with self.assertRaises(BrokenProcessPool):
list(executor.map(_crash_with_data, [data] * 10))


create_executor_tests(ExecutorDeadlockTest,
executor_mixins=(ProcessPoolForkMixin,
Expand Down
@@ -0,0 +1 @@
Fix hanging :mod:`multiprocessing` ``ProcessPoolExecutor`` when a child process crashes while data is being written in the call queue.

0 comments on commit fc537a3

Please sign in to comment.