キューを中心にソリューションを設計するよりも実用的な場合があるため、イテレータースレッドを安全にするための単純なラッパーを作成したいと思います。これまでのところ、私はこれらの トピックからインスピレーションを得て、2つのアイデアを思いつきました。
アイデア1
class LockedIterator(object):
def __init__(self, it):
self._lock = threading.Lock()
self._it = it.__iter__()
if hasattr(self._it, 'close'):
def close(self):
with self._lock:
self._it.close()
self.__setattr__('close', close)
def __iter__(self):
return self
def next(self):
with self._lock:
return self._it.next()
私が気に入らないのは、ジェネレーターの特殊なケースなど、考えられるすべてのメソッドを指定する必要がある場合、少し長くなることです。また、現在は非表示になっている、さらに具体的なメソッドを備えた他のイテレータがあるかもしれません。
アイデア2
class LockedIterator(object):
def __init__(self, it):
self._lock = threading.Lock()
self._it = it.__iter__()
def __getattr__(self, item):
attr = getattr(self._it, item)
if callable(attr):
def hooked(*args, **kwargs):
with self._lock:
return attr(*args, **kwargs)
setattr(self, item, hooked)
return hooked
これはより簡潔ですが、呼び出しをインターセプトすることしかできず、たとえば、プロパティを直接変更することはできません。(これらのプロパティは、問題を防ぐために非表示になっています。)さらに重要なことは、Pythonが私のオブジェクトをイテレーターとして認識しないようにすることです。
リークのある抽象化を作成せずに、すべてのイテレータ(またはさらに良い:すべてのオブジェクト)でこれを機能させるための最良の方法は何ですか?必要のないときにロックすることについてはあまり心配していませんが、それを回避する解決策を考え出すことができれば、素晴らしいです!