threading.RLock not subclassible?

John Gault gry at
Sun Feb 4 08:38:39 EST 2001

[python2.0, i386-linux 2.2.16]
I would like to make a subclass of threading.RLock so I can
add a 'safe_acquire' method.  Safe_acquire would use non-
blocking acquires and sleeps over several iterations to try
to acquire the lock, but would eventually return so my thread
is not forever blocked.

But the RLock class seems to be written in a way discouraging
subclassing: in the threading class I see --

def RLock(*args, **kwargs):
    return apply(_RLock, args, kwargs)class _RLock(_Verbose):
    def __init__(self, verbose=None):
        _Verbose.__init__(self, verbose)
        self.__block = _allocate_lock()
        self.__owner = None
        self.__count = 0

It looks like the author(not identified in the code) is explictly trying
to avoid subclassing...  Does anyone see danger (or stupidity?) in my

class Safe_RLock(threading._RLock):
    '''reentrant 'RLock' with safe acquire method'''
    def __init__(self, timeout=2.0): #default cumulative timeout of 2.0
        self.timeout = timeout

    def safe_acquire(self, timeout=None):
        timeout = timeout or self.timeout
        cumulative_backoff = 0
        while not self.acquire(0):
            # pseudorandom 50ms<delay<200ms to retry lock acquire
            backoff = whrandom.uniform(0.05, 0.2)
            dbug('delaying %.3f seconds for blocked lock' % timeout)
            cumulative_backoff += backoff
            if cumulative_timeout > timeout: # give up after timeout
                dbug('failed to acquire lock after %s seconds' %
                return 0
            return 1

used later as:
        # try to get the lock, but don't block forever...
        if dblock.safe_acquire():
            db[ip] = hostname or '$hostnotfound'
            bug('inverse_lookup: failed to acquire db lock')
        result_queue.put((ip, hostname))

George Young, gry at mediaone dot net

More information about the Python-list mailing list