It is possible to create a count
property for threading._RLock._count
by inheriting from the class and exposing the data from the underlying attribute. This is easily demonstrated by example:
import threading
# noinspection PyProtectedMember
class RLock(threading._RLock):
"""RLock() -> RLock instance with count property"""
@property
def count(self):
"""Count property showing current level of lock ownership."""
return self._count
_thread.RLock
by getting the count via ctypes
?Is it possible to do the same with the _thread.RLock by getting the count via ctypes?
Yes, it is possible, as rlockobject
strunct definition is given:
import ctypes, _thread
class RLock(_thread.RLock):
offsetof_rlock_count = 32 # on 64-bit system
@property
def count(self):
rlock_count_b = ctypes.string_at(id(self)+self.offsetof_rlock_count, 8)
return int.from_bytes(rlock_count_b, 'little', signed=False)
rlock = RLock()
with rlock:
with rlock:
print(rlock.count)
yields:
2
or a more formal version:
class S_rlockobject(ctypes.Structure):
_fields_ = [
('ob_refcnt', ctypes.c_ssize_t),
('ob_type', ctypes.c_void_p),
('rlock_lock', ctypes.c_void_p),
('rlock_owner', ctypes.c_long),
('rlock_count', ctypes.c_ulong),
('in_weakreflist', ctypes.c_void_p),
]
class RLock(_thread.RLock):
def __init__(self):
super().__init__()
self._s = S_rlockobject.from_address(id(self))
@property
def count(self):
return self._s.rlock_count
If it is possible, would the code have any advantages over the version shown above? If it would be advantageous, what code would one have to write to access the count?
Both methods utilize non-public API, it is hard to tell which is better, but I feel the inheriting pure python RLock
implementation is simpler. The performance difference is neglectable here.