call_once를 이용한 Singleton 패턴
18 Aug 2017 | C++ Thread 디자인패턴Thread-Safe Singleton
기본적으로 Singleton 패턴은 Thread-Safe 하지 않습니다. 그래서 생성자에 synchronized
키워드나(Java의 경우) ‘Mutex’ 등을 이용해서 Thread-Safe 하도록 만들어주는 경우가 많습니다. 그게 아니면, 프로그램 실행 초반에 인스턴스를 생성하도록 하는 방법을 많이 씁니다.
C++11 부터 사용가능한 call_once()
를 이용하면 좀 더 간편하게 Singleton 패턴을 사용할 수 있습니다.
std::call_once()
는 std::once_flag()
와 함께 사용하여 복수의 Thread 환경에서 특정 함수를
단 한 번만 구동되도록 할 수 있습니다. 이러한 호출을 ‘Effective Call Once Invocation’라고 합니다.
Singleton.h
#ifndef SNOWTHREAD_SINGLETON_H #define SNOWTHREAD_SINGLETON_H #include <cstdio> #include <mutex> #include <memory> using namespace std; class Singleton { public: static Singleton &getInstance() { call_once(Singleton::mOnceFlag, []() { printf("Singleton Instance is created...\n"); mInstance.reset(new Singleton); }); return *(mInstance.get()); } void log() { printf("hello\n"); } private: static unique_ptr<Singleton> mInstance; static once_flag mOnceFlag; Singleton() = default; Singleton(const Singleton &) = delete; Singleton &operator=(const Singleton &) = delete; }; unique_ptr<Singleton> Singleton::mInstance; once_flag Singleton::mOnceFlag; #endif //SNOWTHREAD_SINGLETON_H
main.cpp
#include "Singleton.h" int main() { Singleton::getInstance().log(); Singleton::getInstance().log(); return 0; }
실행 결과
Singleton Instance is created... hello hello