1. 程式人生 > >ACE中靜態實例管理方式

ACE中靜態實例管理方式

thread con pri operator tcs 添加 space opera 宏定義

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中靜態實例管理方式