zoukankan      html  css  js  c++  java
  • 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
    "),
    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框架来管理内存,便于对系统进行管理与调试。

  • 相关阅读:
    linux(centos 6.4)下安装php memcache服务端及其客户端(详细教程)
    linux下swap问题处理
    mysql锁表查询,binlog日志清理
    Centos7上安装部署frp内网穿透
    配置frp实现内网穿透,域名再也不用备案了
    xp激活码 windows xp产品密钥 xp sp3专业版正版序列号
    windows不能使用剪贴板解决办法
    mysql多主一从配置
    给mysql的root %用户添加grant权限和创建的用户权限
    redis主从及集群配置密码
  • 原文地址:https://www.cnblogs.com/zl1991/p/7612099.html
Copyright © 2011-2022 走看看