Skip to content

Commit 9dfc754

Browse files
authored
Revert "bpo-34172: multiprocessing.Pool leaks resources after being deleted (GH-8450)" (GH-10971)
This reverts commit 97bfe8d.
1 parent 8752dfb commit 9dfc754

File tree

3 files changed

+24
-58
lines changed

3 files changed

+24
-58
lines changed

‎Lib/multiprocessing/pool.py‎

Lines changed: 24 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,8 @@ class Pool(object):
149149
'''
150150
_wrap_exception = True
151151

152-
@staticmethod
153-
def Process(ctx, *args, **kwds):
154-
return ctx.Process(*args, **kwds)
152+
def Process(self, *args, **kwds):
153+
return self._ctx.Process(*args, **kwds)
155154

156155
def __init__(self, processes=None, initializer=None, initargs=(),
157156
maxtasksperchild=None, context=None):
@@ -186,15 +185,13 @@ def __init__(self, processes=None, initializer=None, initargs=(),
186185

187186
self._worker_handler = threading.Thread(
188187
target=Pool._handle_workers,
189-
args=(self._cache, self._taskqueue, self._ctx, self.Process,
190-
self._processes, self._pool, self._inqueue, self._outqueue,
191-
self._initializer, self._initargs, self._maxtasksperchild,
192-
self._wrap_exception)
188+
args=(self, )
193189
)
194190
self._worker_handler.daemon = True
195191
self._worker_handler._state = RUN
196192
self._worker_handler.start()
197193

194+
198195
self._task_handler = threading.Thread(
199196
target=Pool._handle_tasks,
200197
args=(self._taskqueue, self._quick_put, self._outqueue,
@@ -220,62 +217,43 @@ def __init__(self, processes=None, initializer=None, initargs=(),
220217
exitpriority=15
221218
)
222219

223-
@staticmethod
224-
def _join_exited_workers(pool):
220+
def _join_exited_workers(self):
225221
"""Cleanup after any worker processes which have exited due to reaching
226222
their specified lifetime. Returns True if any workers were cleaned up.
227223
"""
228224
cleaned = False
229-
for i in reversed(range(len(pool))):
230-
worker = pool[i]
225+
for i in reversed(range(len(self._pool))):
226+
worker = self._pool[i]
231227
if worker.exitcode is not None:
232228
# worker exited
233229
util.debug('cleaning up worker %d' % i)
234230
worker.join()
235231
cleaned = True
236-
del pool[i]
232+
del self._pool[i]
237233
return cleaned
238234

239235
def _repopulate_pool(self):
240-
return self._repopulate_pool_static(self._ctx, self.Process,
241-
self._processes,
242-
self._pool, self._inqueue,
243-
self._outqueue, self._initializer,
244-
self._initargs,
245-
self._maxtasksperchild,
246-
self._wrap_exception)
247-
248-
@staticmethod
249-
def _repopulate_pool_static(ctx, Process, processes, pool, inqueue,
250-
outqueue, initializer, initargs,
251-
maxtasksperchild, wrap_exception):
252236
"""Bring the number of pool processes up to the specified number,
253237
for use after reaping workers which have exited.
254238
"""
255-
for i in range(processes - len(pool)):
256-
w = Process(ctx, target=worker,
257-
args=(inqueue, outqueue,
258-
initializer,
259-
initargs, maxtasksperchild,
260-
wrap_exception)
261-
)
239+
for i in range(self._processes - len(self._pool)):
240+
w = self.Process(target=worker,
241+
args=(self._inqueue, self._outqueue,
242+
self._initializer,
243+
self._initargs, self._maxtasksperchild,
244+
self._wrap_exception)
245+
)
262246
w.name = w.name.replace('Process', 'PoolWorker')
263247
w.daemon = True
264248
w.start()
265-
pool.append(w)
249+
self._pool.append(w)
266250
util.debug('added worker')
267251

268-
@staticmethod
269-
def _maintain_pool(ctx, Process, processes, pool, inqueue, outqueue,
270-
initializer, initargs, maxtasksperchild,
271-
wrap_exception):
252+
def _maintain_pool(self):
272253
"""Clean up any exited workers and start replacements for them.
273254
"""
274-
if Pool._join_exited_workers(pool):
275-
Pool._repopulate_pool_static(ctx, Process, processes, pool,
276-
inqueue, outqueue, initializer,
277-
initargs, maxtasksperchild,
278-
wrap_exception)
255+
if self._join_exited_workers():
256+
self._repopulate_pool()
279257

280258
def _setup_queues(self):
281259
self._inqueue = self._ctx.SimpleQueue()
@@ -433,20 +411,16 @@ def _map_async(self, func, iterable, mapper, chunksize=None, callback=None,
433411
return result
434412

435413
@staticmethod
436-
def _handle_workers(cache, taskqueue, ctx, Process, processes, pool,
437-
inqueue, outqueue, initializer, initargs,
438-
maxtasksperchild, wrap_exception):
414+
def _handle_workers(pool):
439415
thread = threading.current_thread()
440416

441417
# Keep maintaining workers until the cache gets drained, unless the pool
442418
# is terminated.
443-
while thread._state == RUN or (cache and thread._state != TERMINATE):
444-
Pool._maintain_pool(ctx, Process, processes, pool, inqueue,
445-
outqueue, initializer, initargs,
446-
maxtasksperchild, wrap_exception)
419+
while thread._state == RUN or (pool._cache and thread._state != TERMINATE):
420+
pool._maintain_pool()
447421
time.sleep(0.1)
448422
# send sentinel to stop workers
449-
taskqueue.put(None)
423+
pool._taskqueue.put(None)
450424
util.debug('worker handler exiting')
451425

452426
@staticmethod
@@ -828,7 +802,7 @@ class ThreadPool(Pool):
828802
_wrap_exception = False
829803

830804
@staticmethod
831-
def Process(ctx, *args, **kwds):
805+
def Process(*args, **kwds):
832806
from .dummy import Process
833807
return Process(*args, **kwds)
834808

‎Lib/test/_test_multiprocessing.py‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,13 +2558,6 @@ def test_release_task_refs(self):
25582558
# they were released too.
25592559
self.assertEqual(CountedObject.n_instances, 0)
25602560

2561-
@support.reap_threads
2562-
def test_del_pool(self):
2563-
p = self.Pool(1)
2564-
wr = weakref.ref(p)
2565-
del p
2566-
gc.collect()
2567-
self.assertIsNone(wr())
25682561

25692562
def raising():
25702563
raise KeyError("key")

‎Misc/NEWS.d/next/Library/2018-07-26-10-31-52.bpo-34172.8ovLNi.rst‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)