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