코딩

Start Python #1 Thread safe 싱글톤 패턴

싱글톤 패턴 설명은 다음과 같습니다. 싱글톤 패턴은 클래스가 단 하나만의 인스턴스를 갖도록 보장하고 글로벌 접근이 가능하도록 합니다. The singleton pattern ensures class has only one instance, and provides a global point of access to it. 1

예제 코드를 보시려면 이 링크의 영상을 참조해주세요.

싱글톤 패턴

싱글톤 패턴은 GOF (Gang of Four)이 설명한 디자인 패턴중에 하나입니다.

싱글톤 패턴 클래스 다이어그램

프로젝트를 개발하다보면 단 하나만 존재해야 하는 Object들이 있습니다.

예를 들면, 디바이스 드라이버나 데이터 저장소 그리고 로깅등이 있겠습니다.

저는 이런 경우 글로벌 변수보다 싱글톤 패턴을 사용합니다.

싱글톤으로 인스턴스를 관리해주고 이 또한 Class이니 Method들을 추가할 수 있어 제 프로젝트의 코드가 훨씬 간결해지기 때문입니다.

다음은 파이썬으로 싱글톤 패턴을 구현한 코드입니다.

저는 가끔 멀티 쓰레드를 사용하는 편이어서 Thread Safe 하게 만들었습니다.

파이썬보다 자바등 다른 언어에서는 더더욱 Thread Safe가 필수이므로 싱글톤 패턴에는 반드시 고려해야 하는 사항입니다.

Singleton.py

인스턴스를 만들과 관리하는Sington type을 만들었습니다.

객체가 생성을 호출하면 __call__이 불리게 되고 생성된 인스턴스가 없으면 새로 생성을 하고 이미 생성된게 있으면 해당 인스턴스를 반환하여 줍니다.

별도로 metaclasstyle은 다음 page에 잘 설명되어 있습니다.

나중에 필요시 다른 글에서 추가 설명하도록 하겠습니다.

from threading import Lock

class Singleton(type):
    _instance = None
    _lock = Lock()

    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if not cls._instance:
                cls._instance = super().__call__(*args, **kwargs)
        return cls._instance

SingletonClass.py

다음은 실제 싱글톤으로 생성되는 클래스로 생성할때 인자로 설정하는 name이라는 변수를 갖도록 했습니다.

그리고 2개의 쓰레드로부터 각각 ACLASSBCLASS라는 이름으로 SingletonClass(value)를 하도록 하였습니다.

from Singleton import Singleton
from threading import Thread

class SingletonClass(metaclass=Singleton):
    def __init__(self, name):
        self.name = name

def run(value):
    singleton = SingletonClass(value)
    print(singleton.name)

if __name__ == '__main__':
    processa = Thread(target=run, args=('ACLASS',))
    processb = Thread(target=run, args=('BCLASS',))
    processa.start()
    processb.start()

Test Result

결과는 아래와 같이 ACLASS만 두번 프린트합니다.

즉, 두번째 호출한 SingletonClass('BCLASS')는 인스턴스가 생성되지 않고 처음 생성했던 인스턴스를 참조하게 되었기 때문입니다.

ACLASS
ACLASS

Start Python series

새로 프로그래밍을 시작하는 많은 분들이 Hello world!를 찍고 문법 공부를 하는 것으로 시작합니다.

하지만 실제 프로젝트는 다양한 기술들을 요구하게 됩니다.

그래서 제가 실제 프로젝트를 하면서 자주 경험하는 것들에 대해서 예제코드를 준비하고 라이브러리화하면서 글을 작성하려고 합니다.

각각의 개발자들은 각기의 환경과 프로젝트 규모를 가지고 있어 Django같은 Framework을 사용하지는 않을것입니다.

제가 Python으로 대규모의 프로젝트를 하지도 않을 뿐더러 새로 프로그래밍을 시작하시는 분들이 당장 필요할 것 같지는 않아서 좀 더 Low level api로 구현하는 것으로 진행하겠습니다.

조언이나 추가 질문이 있으면 답글 달아주세요.

  1. Freeman Robson, Head First Design Patterns, O’REILLY, 2014, p179 []

Leave a Reply