mirror of
https://github.com/python/cpython.git
synced 2025-10-15 03:10:29 +00:00
bpo-47029: Fix BrokenPipeError in multiprocessing.Queue at garbage collection and explicit close (#31913)
This commit is contained in:
parent
f629dcfe83
commit
dfb1b9da8a
2 changed files with 15 additions and 12 deletions
|
@ -139,13 +139,10 @@ class Queue(object):
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self._closed = True
|
self._closed = True
|
||||||
try:
|
close = self._close
|
||||||
self._reader.close()
|
if close:
|
||||||
finally:
|
self._close = None
|
||||||
close = self._close
|
close()
|
||||||
if close:
|
|
||||||
self._close = None
|
|
||||||
close()
|
|
||||||
|
|
||||||
def join_thread(self):
|
def join_thread(self):
|
||||||
debug('Queue.join_thread()')
|
debug('Queue.join_thread()')
|
||||||
|
@ -169,8 +166,9 @@ class Queue(object):
|
||||||
self._thread = threading.Thread(
|
self._thread = threading.Thread(
|
||||||
target=Queue._feed,
|
target=Queue._feed,
|
||||||
args=(self._buffer, self._notempty, self._send_bytes,
|
args=(self._buffer, self._notempty, self._send_bytes,
|
||||||
self._wlock, self._writer.close, self._ignore_epipe,
|
self._wlock, self._reader.close, self._writer.close,
|
||||||
self._on_queue_feeder_error, self._sem),
|
self._ignore_epipe, self._on_queue_feeder_error,
|
||||||
|
self._sem),
|
||||||
name='QueueFeederThread'
|
name='QueueFeederThread'
|
||||||
)
|
)
|
||||||
self._thread.daemon = True
|
self._thread.daemon = True
|
||||||
|
@ -211,8 +209,8 @@ class Queue(object):
|
||||||
notempty.notify()
|
notempty.notify()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
|
def _feed(buffer, notempty, send_bytes, writelock, reader_close,
|
||||||
onerror, queue_sem):
|
writer_close, ignore_epipe, onerror, queue_sem):
|
||||||
debug('starting thread to feed data to pipe')
|
debug('starting thread to feed data to pipe')
|
||||||
nacquire = notempty.acquire
|
nacquire = notempty.acquire
|
||||||
nrelease = notempty.release
|
nrelease = notempty.release
|
||||||
|
@ -238,7 +236,8 @@ class Queue(object):
|
||||||
obj = bpopleft()
|
obj = bpopleft()
|
||||||
if obj is sentinel:
|
if obj is sentinel:
|
||||||
debug('feeder thread got sentinel -- exiting')
|
debug('feeder thread got sentinel -- exiting')
|
||||||
close()
|
reader_close()
|
||||||
|
writer_close()
|
||||||
return
|
return
|
||||||
|
|
||||||
# serialize the data before acquiring the lock
|
# serialize the data before acquiring the lock
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Always close the read end of the pipe used by :class:`multiprocessing.Queue`
|
||||||
|
*after* the last write of buffered data to the write end of the pipe to avoid
|
||||||
|
:exc:`BrokenPipeError` at garbage collection and at
|
||||||
|
:meth:`multiprocessing.Queue.close` calls. Patch by Géry Ogam.
|
Loading…
Add table
Add a link
Reference in a new issue