summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2020-03-15 21:26:43 (GMT)
committerGitHub <noreply@github.com>2020-03-15 21:26:43 (GMT)
commit7f5302fed4ff0cc8042e639b29a0664a16bc2702 (patch)
tree8826b850ac54fbd81eb10c6b2b049daab8442bc6 /Lib/test
parent890dcfe4035888f70207eaac05662d6e29606214 (diff)
downloadcpython-7f5302fed4ff0cc8042e639b29a0664a16bc2702.zip
cpython-7f5302fed4ff0cc8042e639b29a0664a16bc2702.tar.gz
cpython-7f5302fed4ff0cc8042e639b29a0664a16bc2702.tar.bz2
bpo-39360: Ensure all workers exit when finalizing a multiprocessing Pool (GH-19009)
When the pull is not used via the context manager or terminate() is called, there is a system in multiprocessing.util that handles finalization of all pools via an atexit handler (the Finalize) class. This class registers the _terminate_pool handler in the registry of finalizers of the module, and that registry is called on interpreter exit via _exit_function. The problem is that the "happy" path with the context manager or manual call to finalize() does some extra steps that _terminate_pool does not. The step that is not executed when the atexit() handler calls _terminate_pool is pinging the _change_notifier queue to unblock the maintenance threads. This commit moves the notification to the _terminate_pool function so is called from both code paths. Co-authored-by: Pablo Galindo <Pablogsal@gmail.com> (cherry picked from commit ac10e0c93218627d1a639db0b7b41714c5f6a883) Co-authored-by: Batuhan Taşkaya <47358913+isidentical@users.noreply.github.com>
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/_test_multiprocessing.py18
1 files changed, 18 insertions, 0 deletions
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index de91242..e64a8e9 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -2778,6 +2778,24 @@ class _TestPoolWorkerLifetime(BaseTestCase):
for (j, res) in enumerate(results):
self.assertEqual(res.get(), sqr(j))
+ def test_worker_finalization_via_atexit_handler_of_multiprocessing(self):
+ # tests cases against bpo-38744 and bpo-39360
+ cmd = '''if 1:
+ from multiprocessing import Pool
+ problem = None
+ class A:
+ def __init__(self):
+ self.pool = Pool(processes=1)
+ def test():
+ global problem
+ problem = A()
+ problem.pool.map(float, tuple(range(10)))
+ if __name__ == "__main__":
+ test()
+ '''
+ rc, out, err = test.support.script_helper.assert_python_ok('-c', cmd)
+ self.assertEqual(rc, 0)
+
#
# Test of creating a customized manager class
#