멀티스레드 환경에서 스레드간 통신을 위해 자료구조를 사용한다고 한다. 하지만 동시에 여러 스레드에서 하나의 변수에 접근시 임계영역 문제가 발생하게 된다. 그렇기 때문에 자료구조 역시 Thread-safe 하게 만들 필요가 있다.
아래는 Thread-safe 구현한 set 클래스 이다.(파이썬 동시성 프로그래밍, 에이콘 출판사 에서 발췌)
from threading import Lock
class LockedSet(set):
def __init__(self, *args, **kwargs):
self._lock= Lock()
super(LockedSet, self).__init__(*args, **kwargs)
def add(self, elem):
with self._lock:
#with keyword는 자원을 얻고 반납하는 경우 사용하는 키워드
super(LockedSet, self).add(elem)
def remove(self, elem):
with self._lock:
super(LockedSet, self).remove(elem)
def __contains__(self, elem):
with self._lock:
super(LockedSet, self).__contains__(elem)
재사용성을 높이면서 하는 방법은 함수 데코레이터를 사용하는 방법이있다.
def lock(method):
def newmethod(self, *args, **kwargs):
with self._lock:
return method(self, *args, **kwargs)
return newmethod
class DecoratorLockedSet(set):
def __init__(self, *args, **kwargs):
self._lock = Lock()
super(DecoratorLockedSet, self).__init__(*args, **kwargs)
@locked_method
def add(self, *args, **kwargs):
return super(DecoratorLockedSet, self).add(elem)
@locked_method
def remove(self, *args, **kwargs):
return super(DecoratorLockedSet, self).remove(elem)
이것보다 더 재사용성을 높이는 방법으로는 클래스 데코레이터를 사용하면 된다.
from threading import Lock
def lock_class(methodNames, lockfactory):
return lambda cls: make_threadsafe(cls, methodNames, lockfactory)
def locked_method(method):
with self._lock:
return method(self, *args, **kwargs)
locked_method.__name__ = f"{locked_method}{method.__name__}"
locked_method.__is_locked =True
return locked_method
def make_threadsafe(cls, methodnames, lockfactory):
init = cls.__init__
def newinit(self, *args, **kwargs):
init(self, *args, **kwargs)
self._lock = lockfactory()
cls.__init__ = newinit
for methodName in methodNames:
oldmethod = getattr(cls, methodName)
newmethod = lock_method(oldmethod)
setattr(cls, methodname, newmethod)
return cls
@lock_class(['add', 'remove'], Lock)
class ClassDecoratorLockedSet(set):
@lock_method
def lockedMethod(self):
print("this section of our code would be thread safe")
'Language > Python' 카테고리의 다른 글
[FactoryBoy] Trouble Shooting (0) | 2021.11.06 |
---|---|
[Python] 파이썬 노답 삼형제(1) - 데코레이터 (0) | 2021.07.17 |
[Python] @property 너 누구야? 후아유 (0) | 2021.03.28 |
[Python] 정적 메소드 staticmethod, classmethod (0) | 2021.03.27 |
[Python] pickle 파일 module '__main__' has no attribute 'something' (0) | 2020.11.22 |