diff options
author | Batuhan Taşkaya <47358913+isidentical@users.noreply.github.com> | 2020-03-15 19:45:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-15 19:45:56 (GMT) |
commit | ac10e0c93218627d1a639db0b7b41714c5f6a883 (patch) | |
tree | e736b856ff7c84113e035e67389d8246e177a859 /Lib/test/_test_multiprocessing.py | |
parent | c81609e44eed641d3b8a137daa31ef35501c1f85 (diff) | |
download | cpython-ac10e0c93218627d1a639db0b7b41714c5f6a883.zip cpython-ac10e0c93218627d1a639db0b7b41714c5f6a883.tar.gz cpython-ac10e0c93218627d1a639db0b7b41714c5f6a883.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>
Diffstat (limited to 'Lib/test/_test_multiprocessing.py')
-rw-r--r-- | Lib/test/_test_multiprocessing.py | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b985d51..4a87b17 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2780,6 +2780,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 # |