def release(self):
        """Release the lock, allowing another thread that is blocked waiting for
           the lock to acquire the lock.  The lock must be in the locked state,
           but it needn't be locked by the same thread that unlocks it."""
        cdef long candidate
        if self.locked==0:
            raise Exception('this lock is not locked')
        else:
            candidate = PyThread_get_thread_ident()
            if candidate!=self.locker:
                raise Exception('thread %i cannot release lock owned by thread %i'%(candidate,self.locker))
            else:
                self.locked = self.locked - 1
                if self.locked==0:
                    PyThread_release_lock(self.lock)
Release the lock, allowing another thread that is blocked waiting for
           the lock to acquire the lock.  The lock must be in the locked state,
           but it needn't be locked by the same thread that unlocks it.
recipes/Python/310792_native_implementatithreadingLock_threadingRLock_/recipe-310792.py