ACE中靜態實例管理方式
ACE中的很多類使用了單例模式,為了便於管理單例對象,ACE使用了一個組件——ACE_Framework_Component來專門管理。
我們以ACE_Reactor這個單例類的創建和釋放為例。
1、Reactor.cpp中,包括了類的創建釋放。其中,單例模式的接口有兩個instance函數提供——有參和無參。
首先來看無參instance:
1 ACE_Reactor * 2 ACE_Reactor::instance (void) 3 { 4 ACE_TRACE ("ACE_Reactor::instance"); 5 6 if (ACE_Reactor::reactor_ == 0) 7 { 8 // Perform Double-Checked Locking Optimization. 9 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, 10 *ACE_Static_Object_Lock::instance (), 0)); 11 12 if (ACE_Reactor::reactor_ == 0) 13 { 14 ACE_NEW_RETURN (ACE_Reactor::reactor_,15 ACE_Reactor, 16 0); 17 ACE_Reactor::delete_reactor_ = true; //由於動態生成了一個ACE_Reactor對象,所以將delete_reactor_字段設為true 18 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_) //將Singleton對象註冊到一個統一的管理器中 19 } 20 }21 return ACE_Reactor::reactor_; 22 }
這裏使用了經典的雙檢鎖的實現方式。ACE_MT宏會根據系統是否啟用多線程來采取相應的操作:如果系統沒有啟用多線程,那麽它的定義為空,這樣可以避免給單線程系統添加額外的負擔;否則它會執行宏定義的操作,實現方式如下:
1 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 2 # define ACE_MT(X) X 3 # else 4 # define ACE_MT(X) 5 # endif /* ACE_MT_SAFE */
有參instance:
1 ACE_Reactor * 2 ACE_Reactor::instance (ACE_Reactor *r, bool delete_reactor) 3 { 4 ACE_TRACE ("ACE_Reactor::instance"); 5 6 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, 7 *ACE_Static_Object_Lock::instance (), 0)); 8 ACE_Reactor *t = ACE_Reactor::reactor_; 9 ACE_Reactor::delete_reactor_ = delete_reactor; 10 11 ACE_Reactor::reactor_ = r; 12 13 // We can‘t register the Reactor singleton as a framework component twice. 14 // Therefore we test to see if we had an existing reactor instance, which 15 // if so means it must have already been registered. 16 if (t == 0) 17 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_); 18 19 return t; 20 }
這裏是為了保證靈活性,我們可以創建一個需要的定制reactor並傳入ACE_Reactor。具體使用方式如下:
1 Ace_Reactor_Impl *impl=0; 2 impl = new ACE_Select_Reactor(); 3 ACE_Reactor *reactor=0; 4 reactor=new ACE_Reactor(impl); 5 ACE_Reactor::instance(reactor);
2、生成了單例對象後,通過宏ACE_REGISTER_FRAMEWORK_COMPONENT將其註冊到ACE_Framework_Component中,其定義如下:
/// This macro should be called in the instance() method /// of the Concrete class that will be managed. Along /// with the appropriate template instantiation. #define ACE_REGISTER_FRAMEWORK_COMPONENT(CLASS, INSTANCE) \ ACE_Framework_Repository::instance ()->register_component (new ACE_Framework_Component_T<CLASS> (INSTANCE));
可以看到其將Singleton對象封裝進了一個接口類ACE_Framework_Component_T並註冊到ACE_Framework_Repository中進行統一管理。
3、下面來看一下ACE_Framework_Component_T類的實現。
ACE_Framework_Component_T.h
1 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 2 3 /** 4 * @class ACE_Framework_Component_T 5 * 6 * @brief This class inherits the interface of the abstract 7 * ACE_Framework_Component class and is instantiated with the 8 * implementation of the concrete component class @c class Concrete. 9 * 10 * This design is similar to the Adapter and Decorator patterns 11 * from the ``Gang of Four‘‘ book. Note that @c class Concrete 12 * need not inherit from a common class since ACE_Framework_Component 13 * provides the uniform virtual interface! (implementation based on 14 * ACE_Dumpable_Adapter in <ace/Dump_T.h>. 15 */ 16 template <class Concrete> 17 class ACE_Framework_Component_T : public ACE_Framework_Component 18 { 19 public: 20 // = Initialization and termination methods. 21 22 /// Constructor. 23 ACE_Framework_Component_T (Concrete *concrete); 24 25 /// Destructor. 26 ~ACE_Framework_Component_T (void); 27 28 /// Close the contained singleton. 29 void close_singleton (void); 30 31 ACE_ALLOC_HOOK_DECLARE; 32 }; 33 34 ACE_END_VERSIONED_NAMESPACE_DECL
ACE_Framework_Component_T.cpp
1 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 2 3 template <class Concrete> 4 ACE_Framework_Component_T<Concrete>::ACE_Framework_Component_T (Concrete *concrete) 5 : ACE_Framework_Component ((void *) concrete, concrete->dll_name (), concrete->name ()) 6 { 7 ACE_TRACE ("ACE_Framework_Component_T<Concrete>::ctor"); 8 } 9 10 template <class Concrete> 11 ACE_Framework_Component_T<Concrete>::~ACE_Framework_Component_T (void) 12 { 13 ACE_TRACE ("ACE_Framework_Component_T<Concrete>::~ACE_Framework_Component_T"); 14 Concrete::close_singleton (); 15 } 16 17 ACE_ALLOC_HOOK_DEFINE_Tt(ACE_Framework_Component_T) 18 19 template <class Concrete> void 20 ACE_Framework_Component_T<Concrete>::close_singleton (void) 21 { 22 ACE_TRACE ("ACE_Framework_Component_T<Concrete>::close_singleton"); 23 Concrete::close_singleton (); 24 } 25 26 ACE_END_VERSIONED_NAMESPACE_DECL
可以看到該類主要有構造函數、析構函數、和close_singleton。其中close_singleton會調用模板concrete即傳入的單例對象的靜態close_singleton函數。
1 void 2 ACE_Reactor::close_singleton (void) 3 { 4 ACE_TRACE ("ACE_Reactor::close_singleton"); 5 6 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, 7 *ACE_Static_Object_Lock::instance ())); 8 9 if (ACE_Reactor::delete_reactor_) 10 { 11 delete ACE_Reactor::reactor_; 12 ACE_Reactor::reactor_ = 0; 13 ACE_Reactor::delete_reactor_ = false; 14 } 15 }
4、對於ACE_Framework_Repository,register_component函數首先會遍歷component查找該singleton對象是否已存在,而後會將其加入列表。
1 int 2 ACE_Framework_Repository::register_component (ACE_Framework_Component *fc) 3 { 4 ACE_TRACE ("ACE_Framework_Repository::register_component"); 5 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); 6 int i; 7 8 // Check to see if it‘s already registered 9 for (i = 0; i < this->current_size_; i++) 10 if (this->component_vector_[i] && 11 fc->this_ == this->component_vector_[i]->this_) 12 { 13 ACELIB_ERROR_RETURN ((LM_ERROR, 14 "AFR::register_component: error, compenent already registered\n"), 15 -1); 16 } 17 18 if (i < this->total_size_) 19 { 20 this->component_vector_[i] = fc; 21 ++this->current_size_; 22 return 0; 23 } 24 25 return -1; 26 }
5、補充:對於ACE_Framework_Component_T有很有意思的地方,在聲明中有這樣一個宏:ACE_ALLOC_HOOK_DECLARE,其定義如下:
1 # if defined (ACE_HAS_ALLOC_HOOKS) 2 # define ACE_ALLOC_HOOK_DECLARE 3 void *operator new (size_t bytes); 4 void *operator new (size_t bytes, void *ptr); 5 void *operator new (size_t bytes, const std::nothrow_t &) throw (); 6 void operator delete (void *ptr); 7 void operator delete (void *ptr, const std::nothrow_t &); 8 void *operator new[] (size_t size); 9 void operator delete[] (void *ptr); 10 void *operator new[] (size_t size, const std::nothrow_t &) throw (); 11 void operator delete[] (void *ptr, const std::nothrow_t &)
定義中有宏:ACE_ALLOC_HOOK_DEFINE_Tt(ACE_Framework_Component_T):
1 # if defined (ACE_HAS_ALLOC_HOOKS) 2 …… 3 # define ACE_ALLOC_HOOK_DEFINE_Tt(CLASS) 4 ACE_GENERIC_ALLOCS (ACE_ALLOC_HOOK_HELPER_Tt, CLASS)
1 # define ACE_GENERIC_ALLOCS(MAKE_PREFIX, CLASS) 2 MAKE_PREFIX (void *, CLASS)::operator new (size_t bytes) 3 { 4 void *const ptr = ACE_Allocator::instance ()->malloc (bytes); 5 if (ptr == 0) 6 throw std::bad_alloc (); 7 return ptr; 8 } 9 MAKE_PREFIX (void *, CLASS)::operator new (size_t, void *ptr) { return ptr; }10 MAKE_PREFIX (void *, CLASS)::operator new (size_t bytes, 11 const std::nothrow_t &) throw () 12 { return ACE_Allocator::instance ()->malloc (bytes); } 13 MAKE_PREFIX (void, CLASS)::operator delete (void *ptr) 14 { if (ptr) ACE_Allocator::instance ()->free (ptr); } 15 MAKE_PREFIX (void, CLASS)::operator delete (void *ptr, 16 const std::nothrow_t &) 17 { if (ptr) ACE_Allocator::instance ()->free (ptr); } 18 MAKE_PREFIX (void *, CLASS)::operator new[] (size_t size) 19 { 20 void *const ptr = ACE_Allocator::instance ()->malloc (size); 21 if (ptr == 0) 22 throw std::bad_alloc (); 23 return ptr; 24 } 25 MAKE_PREFIX (void, CLASS)::operator delete[] (void *ptr) 26 { if (ptr) ACE_Allocator::instance ()->free (ptr); } 27 MAKE_PREFIX (void *, CLASS)::operator new[] (size_t size, 28 const std::nothrow_t &) throw ()29 { return ACE_Allocator::instance ()->malloc (size); } 30 MAKE_PREFIX (void, CLASS)::operator delete[] (void *ptr, 31 const std::nothrow_t &) 32 { if (ptr) ACE_Allocator::instance ()->free (ptr); }
而如果宏定義ACE_HAS_ALLOC_HOOKS未定義,則全部宏為空。
1 # else 2 # define ACE_ALLOC_HOOK_DECLARE struct Ace_ {} /* Just need a dummy... */ 3 # define ACE_ALLOC_HOOK_DEFINE(CLASS) 4 # define ACE_ALLOC_HOOK_DEFINE_Tt(CLASS) 5 # define ACE_ALLOC_HOOK_DEFINE_Tc(CLASS) 6 # define ACE_ALLOC_HOOK_DEFINE_Tcc(CLASS) 7 # define ACE_ALLOC_HOOK_DEFINE_Tccc(CLASS) 8 # define ACE_ALLOC_HOOK_DEFINE_Tccct(CLASS) 9 # define ACE_ALLOC_HOOK_DEFINE_Tc4(CLASS) 10 # define ACE_ALLOC_HOOK_DEFINE_Tc5(CLASS) 11 # define ACE_ALLOC_HOOK_DEFINE_Tc6(CLASS) 12 # define ACE_ALLOC_HOOK_DEFINE_Tc7(CLASS) 13 # define ACE_ALLOC_HOOK_DEFINE_Ty(CLASS) 14 # define ACE_ALLOC_HOOK_DEFINE_Tyc(CLASS) 15 # define ACE_ALLOC_HOOK_DEFINE_Tycc(CLASS) 16 # define ACE_ALLOC_HOOK_DEFINE_Tcy(CLASS) 17 # define ACE_ALLOC_HOOK_DEFINE_Tcyc(CLASS) 18 # define ACE_ALLOC_HOOK_DEFINE_Tca(CLASS) 19 # define ACE_ALLOC_HOOK_DEFINE_Tco(CLASS) 20 # define ACE_ALLOC_HOOK_DEFINE_Tcoccc(CLASS) 21 # define ACE_ALLOC_HOOK_DEFINE_Tcs(CLASS) 22 # define ACE_ALLOC_HOOK_DEFINE_Tmcc(CLASS) 23 # endif /* ACE_HAS_ALLOC_HOOKS */
這裏可以在編譯時選擇是否添加內存管理鉤子hook,通過ACE框架來管理內存,便於對系統進行管理與調試。
ACE中靜態實例管理方式