본문 바로가기

Robotics/Software Tech.

(c++)Singleton pattern 클래스를 멀티쓰레드에서 안전하게 만드는 방법



프로그램을 구성하다보면, 전역적으로 단일 인스턴스를 가져야 하는 모듈을 만들어야 하는 경우가 분명 있다. 이럴때 싱글톤(Singleton) 패턴으로 클래스를 구성하게 되는데..

문제는 이 패턴이 멀티쓰레드에서 안전하지 않다는 것이다.


아래는 일반적인 싱글톤 패턴의 코드이다.




문제는 최초에 두개의 Thread가 연속으로 GetInstance()를 호출 했을때에 instance의 null체크에서 두 thread가 모두 null이 될 가능성이 있다는 것이다.

이것을 해결하기위해서는 몇가지 솔루션이 있다.


1. criticalsection 사용



동시에 두 thread의 접근을 방지하여 안전성을 확보하자는 것인데, 문제는 criticalsection이 성능면에서는 별로 좋지 않다고 한다.



2. 최초에 getinstance() 호출하여 미리 인스턴스 생성

그냥 멀티쓰레드가 돌기전에  main thread에서 getinstance()를 호출하여 인스턴스를 만들어버리자는 것.

그러면 null로 체크될 가능성이 없기때문이다.


3. Double Check Locking



instance 체크를 두번하여 안정성을 확보하는 방법.

하지만, 논문(http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf)에서는 이 방법이 결코 thread safe하지 않다고 함.




그리고, C++11을 사용한다면, getinstance 내에서 null 체크를 해서 할당 할 것이 아니라, 그냥 함수 내부에 static으로 instance를 만드는 것이 확실하다는 의견도 있다.




참고 : 

1. http://www.codeproject.com/Articles/96942/Singleton-Design-Pattern-and-Thread-Safety

2. http://stackoverflow.com/questions/2576022/efficient-thread-safe-singleton-in-c