zoukankan      html  css  js  c++  java
  • ACE服务端编程4:ACE跨平台之运行时初始化和关闭

    参考APG里的说法:平台差异及不兼容性的一个特别的方面,是对象的运行时初始化和程序关闭时这些对象的相应析构。

    ACE为了明确管理对象的清理,定义了ACE_Object_Manager类,这个类不仅涉及到对象的管理,还与ACE库的初始化与关闭相关。

    ACE中应用了大量的设计模式,本篇顺便研究ACE的程序入口函数替换机制分析。

    ACE库的初始化与关闭


    应用要确保在使用ACE库时正确的初始化和关闭,有以下两种常用方式:

    1、使用ACE_TMAIN宏作为程序入口函数;

    2、使用ACE::init()和ACE::fini()明确初始化和关闭ACE库。

    ACE_TMAIN宏会对程序入口函数进行替换,已在程序执行前和执行后加入初始化代码,对ACE程序入口函数替换机制分析,可以使用编译器展开ACE_TMAIN的代码:

    int ace_main_i (int, char *[]);  
    __declspec (dllimport) int ace_os_main_i (ACE_Main_Base&, int, char *[]); 
    class ACE_Main : public ACE_Main_Base 
    {
    int run_i (int, char *[]);}; 
    inline int ACE_Main::run_i (int argc, char *argv[]) { return ace_main_i (argc, argv); }  
    int main (int argc, char *argv[])
    { 
    ACE_Main m; return m.run (argc, argv); 
    } 
    int ace_main_i (int argc, ACE_TCHAR * argv[])
    {
    	
    	return 0;
    }
    

    可以看到真正的main函数体被替换为:ACE_Main m; return m.run (argc, argv);而程序代码被包括到ace_main_i函数中。

    ACE_Main的实例对象m是一个main函数内的栈对象,在main函数开始构造,在函数的结束析构。

    ACE_Main类是一个生成类,继承自ACE_Main_Base类,调用其run函数。

    ACE_Main_Base在ace/Os_main.h类中定义,代码片段如下:

    ACE_Main_Base::ACE_Main_Base ()
    {
      ACE::init ();
    }
    
    ACE_Main_Base::~ACE_Main_Base ()
    {
      ACE::fini ();
    }
    
    int ACE_Main_Base::run (int argc, char *argv[])
    {
      return this->run_i (argc, argv);
    }
    

    可以看到其构造函数和析构函数也分别通过ACE::init()和ACE::fini()初始化和关闭ACE库。

    研究ACE的宏展开也学习一种入口函数替换机制。

    跟踪ACE::init()


    通过展开ACE_TMAIN宏,发现最终还是在main函数的开始初调用了ACE::init函数,这个函数定义在ace/Init_Ace.cpp中:

    int
    ACE::init (void)
    {
      // Don't use ACE_TRACE, because Object_Manager might not have been
      // instantiated yet.
      // ACE_TRACE ("ACE::init");
    
      ++ACE::init_fini_count_;
    
      return ACE_Object_Manager::instance ()->init ();
    }
    

    init的函数体非常简单,就是初始化ACE_Object_Manager,也就回到本文开始的主体:这个类不仅涉及到对象的管理,还与ACE库的初始化与关闭相关。

    fini函数与此类似,调用了ACE_Object_Manager的清理函数,有兴趣的可以查看源代码。

    ACE_Object_Manager


    ACE_Object_Manager类之所以与ACE库的初始化和关闭相关,是因为ACE_Object_Manager不仅可以帮助应用能按正确的方式清理对象,ACE库内部的对象管理也依赖于ACE_Object_Manager。

    至于ACE_Object_Manager的init函数中的代码可以不必过多深究,主要是实例化一组ACE对象,用以给ACE的内部机制提供支持,并在关闭时销毁这些对象。

    ACE_Object_Manager提供了at_exit函数,允许应用向其登记对象,并在关闭时会以登记次序相反的次序销毁所登记的对象。

    向ACE_Object_Manager登记的对象必须继承自ACE_Cleanup,并实现cleanup()方法进行清理工作;对于基本类型的对象可以使用at_exit的重载函数传递一个ACE_CLEANUP_FUNC的回调函数。

    ACE_Object_Manager的API:http://www.dre.vanderbilt.edu/Doxygen/6.0.0/html/libace-doc/a00355.html

    要保证ACE_Object_Manager能够正确的清理对象,必须满足以下两条:

    1、永远不要直接调用exit(),让main函数通过return返回(推荐阅读:exit & abort & 析构 & 异常 );

    2、确保ACE_Object_Manager成功初始化。

    ACE非常有名的单例模式也是关联到ACE_Object_Manager,后期有机会单独写出来。


    记录,为更好的自己!

  • 相关阅读:
    辅助方法
    扩展方法学习发展之路
    对IOC模式与容器Autofac在MVC里面的一些用法
    Qlikview Session Recovery
    SNOY VAIO 索尼电脑亮度自动变暗
    EXCEL2010数据挖掘插件 下载地址
    Ubuntu20.04 源码安装完应用 如何将应用程序添加到启动器
    flask + flask_restplus+ blueprints 脚手架
    闭包
    操作方法
  • 原文地址:https://www.cnblogs.com/ym123/p/4523477.html
Copyright © 2011-2022 走看看