mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
Issue #17555: Fix ForkAwareThreadLock so that size of after fork
registry does not grow exponentially with generation of process.
This commit is contained in:
commit
b147f60a38
3 changed files with 38 additions and 2 deletions
|
@ -322,10 +322,13 @@ atexit.register(_exit_function)
|
||||||
|
|
||||||
class ForkAwareThreadLock(object):
|
class ForkAwareThreadLock(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self._reset()
|
||||||
|
register_after_fork(self, ForkAwareThreadLock._reset)
|
||||||
|
|
||||||
|
def _reset(self):
|
||||||
self._lock = threading.Lock()
|
self._lock = threading.Lock()
|
||||||
self.acquire = self._lock.acquire
|
self.acquire = self._lock.acquire
|
||||||
self.release = self._lock.release
|
self.release = self._lock.release
|
||||||
register_after_fork(self, ForkAwareThreadLock.__init__)
|
|
||||||
|
|
||||||
class ForkAwareLocal(threading.local):
|
class ForkAwareLocal(threading.local):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -3455,13 +3455,43 @@ class TestNoForkBomb(unittest.TestCase):
|
||||||
self.assertEqual('123', out.decode('ascii').rstrip())
|
self.assertEqual('123', out.decode('ascii').rstrip())
|
||||||
self.assertEqual('', err.decode('ascii'))
|
self.assertEqual('', err.decode('ascii'))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Issue #17555: ForkAwareThreadLock
|
||||||
|
#
|
||||||
|
|
||||||
|
class TestForkAwareThreadLock(unittest.TestCase):
|
||||||
|
# We recurisvely start processes. Issue #17555 meant that the
|
||||||
|
# after fork registry would get duplicate entries for the same
|
||||||
|
# lock. The size of the registry at generation n was ~2**n.
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def child(cls, n, conn):
|
||||||
|
if n > 1:
|
||||||
|
p = multiprocessing.Process(target=cls.child, args=(n-1, conn))
|
||||||
|
p.start()
|
||||||
|
p.join()
|
||||||
|
else:
|
||||||
|
conn.send(len(util._afterfork_registry))
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def test_lock(self):
|
||||||
|
r, w = multiprocessing.Pipe(False)
|
||||||
|
l = util.ForkAwareThreadLock()
|
||||||
|
old_size = len(util._afterfork_registry)
|
||||||
|
p = multiprocessing.Process(target=self.child, args=(5, w))
|
||||||
|
p.start()
|
||||||
|
new_size = r.recv()
|
||||||
|
p.join()
|
||||||
|
self.assertLessEqual(new_size, old_size)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
testcases_other = [OtherTest, TestInvalidHandle, TestInitializers,
|
testcases_other = [OtherTest, TestInvalidHandle, TestInitializers,
|
||||||
TestStdinBadfiledescriptor, TestWait, TestInvalidFamily,
|
TestStdinBadfiledescriptor, TestWait, TestInvalidFamily,
|
||||||
TestFlags, TestTimeouts, TestNoForkBomb]
|
TestFlags, TestTimeouts, TestNoForkBomb,
|
||||||
|
TestForkAwareThreadLock]
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
|
@ -42,6 +42,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #17555: Fix ForkAwareThreadLock so that size of after fork
|
||||||
|
registry does not grow exponentially with generation of process.
|
||||||
|
|
||||||
- Issue #17707: multiprocessing.Queue's get() method does not block for short
|
- Issue #17707: multiprocessing.Queue's get() method does not block for short
|
||||||
timeouts.
|
timeouts.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue