summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/multiprocessing/pool.py7
-rw-r--r--Lib/test/_test_multiprocessing.py18
2 files changed, 23 insertions, 2 deletions
diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py
index b223d6a..41dd923 100644
--- a/Lib/multiprocessing/pool.py
+++ b/Lib/multiprocessing/pool.py
@@ -651,8 +651,6 @@ class Pool(object):
def terminate(self):
util.debug('terminating pool')
self._state = TERMINATE
- self._worker_handler._state = TERMINATE
- self._change_notifier.put(None)
self._terminate()
def join(self):
@@ -682,7 +680,12 @@ class Pool(object):
# this is guaranteed to only be called once
util.debug('finalizing pool')
+ # Notify that the worker_handler state has been changed so the
+ # _handle_workers loop can be unblocked (and exited) in order to
+ # send the finalization sentinel all the workers.
worker_handler._state = TERMINATE
+ change_notifier.put(None)
+
task_handler._state = TERMINATE
util.debug('helping task handler/workers to finish')
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
#