2017-11-27 11 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. それは​​を経由して、カウントを取得することにより、_thread.RLockと同じことを行うことは可能です:これは、簡単に例により実証されますか?
  2. 可能であれば、コードは上記のバージョンよりも利点がありますか?
  3. 有利な場合は、カウントにアクセスするためにどのコードを書き込む必要がありますか?
+0

なぜあなたはctypesまたはサブクラスをまったく必要としますか? 'threading._RLock'の実装の詳細にアクセスする場合は、オブジェクトの' _count'属性に 'whatever_rlock._count'として直接アクセスしてみませんか? – user2357112

+0

アンダースコアが実際に何かをしているという印象を受けていますか?それは単なるアンダースコアです。 Pythonには 'private'や' protected'アクセスはありません。 Javaのようなアクセス制御をバイパスするために、いくつかの 'klass.getDeclaredField( '_ count').getInt(lock)'リフレクションAPIを使う必要はありません。しかし、他のライブラリの実装の詳細を突き止めることは、まだ悪い考えです。 – user2357112

+0

@ user2357112 '_thread.RLock'はC言語で実装されており、' count'属性を公開していません。おそらく 'ctypes'を介してアクセスする必要があります。サブクラスは、データを取得するための整然としたAPIを提供できます。 'threading._RLock._count'はPythonでアクセス可能です。Pythonで実装されているためですが、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を使用していますが、どちらが良いかわかりにくいですが、継承している純粋なPython RLockの実装は簡単です。パフォーマンスの違いはここでは無視できます。

+0

あなたの優れた答えをありがとう!私はあなたの正式なバージョンがより好きです。実稼働環境にとっては良いと思われるからです。 –

+0

@ noctis-skytower最初のバージョンは内部の詳細を出すことです、あなたのフィードバックのおかげで。 – georgexsh

関連する問題