Contents
ACE_Singleton<> 를 이용한, 쉽고 빠른 싱글톤 만들기
ACE 에서 제공하는 ACE_Singleton< TYPE, ACE_LOCK > Class Template 를 이용하면 간단하게 싱글톤 클래스를 만들수 있다. 싱글톤 패턴에 대해서는 여기 적지 않고, 간단히 사용법만 적는다.
멀티 쓰레드 환경에서의 싱글톤 생성때문에, ACE_Singleton 는 ACE_LOCK 을 인자로 받지만, 여기서는 그걸 무시하고 ACE_Null_Mutex 만 쓴다.( 원 예제가 그래서... ) 만약 locking 에 신경써야 한다면, ACE_Recursive_Thread_Mutex 를 쓰도록 하자.
#include "ace/Singleton.h" class foo { friend class ACE_Singleton<foo, ACE_Null_Mutex>; private: foo() { cout << "foo ctor" << endl; } ~foo() { cout << "foo dtor" << endl; } }; typedef ACE_Singleton<foo, ACE_Null_Mutex> FOO;
코드를 보면 알겠지만, 세가지만 신경써주면 된다.
friend class ACE_Singleton<foo, ACE_Null_Mutex>; 를 추가한다.
- 생성자와 소멸자를 private 으로 만들어서, 직접적인 생성을 막는다.
typedef ACE_Singleton<foo, ACE_Null_Mutex> FOO; typedefine 을 쓰자.
실제로 불러서 쓸때는 instance() 멤버함수를 통해 인스턴스를 얻을수 있다.
int ACE_MAIN(int argc, ACE_TCHAR* argv[]) { FOO::instance(); { FOO::instance(); } FOO::instance(); }
위 코드를 출력해보면, 한번만 만들어 진다는것을 알수 있다.
instnace() 가 돌려주는 값은 포인터이다. 이 값을 copy 해두고 쓰려면,
foo& f = *FOO::instance(); f.test(); f.func(); f.suck();
음... 이건 모양이 안좋군. 가져다 쓰는 입장에서 원 클래스 이름 foo 와 디파인된 FOO 를 모두 알아야 하다니?
ACE_Unmanaged_Singleton<TYPE, ACE_LOCK>
ACE_Singleton 과 같지만, ACE_Object_Manager 에 등록하지 않는다고 한다. 오호라 ACE_Object_Manager 가 뭘 하는지 알아야겠구나. 그전까진 그냥 원문만 적어둔다.
Same as ACE_Singleton, except does _not_ register with ACE_Object_Manager for destruction. This version of ACE_Singleton can be used if, for example, its DLL will be unloaded before the ACE_Object_Manager destroys the instance. Unlike with ACE_Singleton, the application is responsible for explicitly destroying the instance after it is no longer needed (if it wants to avoid memory leaks, at least). The close() static member function must be used to explicitly destroy the Singleton. Usage is the same as for ACE_Singleton, but note that if you you declare a friend, the friend class must still be an *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton.
ACE_TSS_Singleton<TYPE, ACE_LOCK>
thread-specific 한 싱글톤을 만들어내는 녀석인거 같다. 역시 자세한 내용은 뒤로 미룬다.
This class uses the Adapter pattern to turn ordinary classes into Thread-specific Singletons optimized with the Double-Checked Locking optimization pattern. This implementation is another variation on the GoF Singleton pattern. In this case, a single <ACE_TSS_Singleton<TYPE, LOCK> > instance is allocated here, not a <TYPE> instance. Each call to the <instance> static method returns a Singleton whose pointer resides in thread-specific storage. As with ACE_Singleton, we use the ACE_Object_Manager so that the Singleton can be cleaned up when the process exits. For this scheme to work, a (static) cleanup() function must be provided. ACE_Singleton provides one so that TYPE doesn't need to.
ACE_Unmanaged_TSS_Singleton< TYPE, ACE_LOCK >
ACE_TSS_Singleton<TYPE, ACE_LOCK> 가 ACE_Object_Manager 에 등록되지 않는 놈이겠지. 이놈도 자세히 공부하는건 나중으로.
ACE_Cleanup Class
ACE_Object_Manager 에 의해 clean 되는 클래스들의 base 클래스랜다. 위의 싱글톤 클래스들은 모두 이녀석들의 자식이었다. ACE_Object_Manager 를 공부할때 같이 봐야겠군.
