2017-11-27 1 views
1

threading._RLock._count에 대해 count 속성을 만들려면 클래스를 상속하고 기본 특성의 데이터를 노출해야합니다.ctypes를 통해 _thread.RLock 수에 편리하게 액세스 할 수 있습니까?

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 
  1. ctypes을 통해 수를 얻어서 _thread.RLock와 동일한 기능을 수행 할 수 있는가 :이 쉽게 예에 의해 입증된다?
  2. 가능한 경우 코드가 위에 표시된 버전보다 장점이 있습니까?
  3. 이점이 있다면 카운트에 액세스하려면 어떤 코드를 작성해야합니까?
+0

왜 ctypes 또는 하위 클래스가 필요합니까? 'threading._RLock'의 구현 세부 사항에 접근하려면 객체의'_count' 속성에'whatever_rlock._count'로 직접 액세스하지 않는 것이 어떻습니까? – user2357112

+0

실제로 언더 스코어가 뭔가를하고 있다는 인상을 받고 있습니까? 그것은 단지 밑줄입니다. 파이썬에는'private' 또는'protected' 접근이 없습니다. Java와 같은 액세스 제어를 우회하기 위해'klass.getDeclaredField ('_ count'). getInt (lock)'reflection API를 거칠 필요가 없습니다. 단지 액세스 제어가 없기 때문입니다. 그러나 다른 라이브러리의 구현 세부 사항을 찌르는 것은 여전히 ​​나쁜 생각입니다. – user2357112

+0

@ user2357112'_thread.RLock'은 C에서 구현되고'count' 속성을 노출시키지 않으며,'ctypes'를 통해 접근해야 할 수도 있습니다. 서브 클래스는 데이터를 얻기위한 질서 정연한 API를 제공 할 수 있습니다. 'threading._RLock._count'는 파이썬에서 접근 가능합니다. 파이썬에서 구현 되었기 때문에, C에서의 구현은 그러한 옵션을 쉽게 허용하지 않습니다. –

답변

2

이하는 ctypes를 통해 수를 얻어서 _thread.RLock와 동일한 기능을 수행 할 수 있습니까?

rlockobject strunct definition이 주어진대로 네, 가능합니다 :

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) 

수율 :

2 

또는 더 공식적인 버전 :

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 

는 만약을 가능하다 e, 코드는 위에 표시된 버전보다 장점이 있습니까? 이점이 있다면 카운트에 액세스하려면 어떤 코드를 작성해야합니까?

두 가지 방법 모두 비공개 API를 사용하므로 어떤 것이 더 좋을지는 알 수 없지만 순수한 파이썬 RLock 구현이 더 단순하다고 생각합니다. 여기서 성능 차이는 무시할 수 있습니다.

+0

훌륭한 답변을 보내 주셔서 감사합니다. 프로덕션 환경에서 더 좋을 것처럼 보였으므로 정식 버전이 더 좋습니다. –

+0

@ noctis-skytower 첫 번째 버전은 귀하의 의견에 감사 드리며 내부 세부 사항을 전시하는 것입니다. – georgexsh

관련 문제