参考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,后期有机会单独写出来。


记录,为更好的自己!

ACE服务端编程4:ACE跨平台之运行时初始化和关闭的更多相关文章

  1. ACE服务端编程3:ACE跨平台之分配堆内存

    ACE服务端编程系列的第三篇,探究ACE解决不同编译器之间分配堆内存的差异. 在ACE的官方示例中会看到大量的ACE_NEW_RETURN,ACE_NEW这样的宏,这是ACE为了消除不同编译器编译的代 ...

  2. ACE服务端编程2:ACE跨平台之数据类型和宽字符

    ACE网络库的主要优势之一就是跨平台,ACE提供了操作系统API和编译器级别的跨平台解决方法,使开发人员不用再去关心操作系统和编译器的差异,但因此也带来了ACE的复杂性. ACE网络库的组织结构主要分 ...

  3. ACE服务端编程1:使用VS2010编译ACE6.0及从ACE5.6升级的注意事项

    ACE是一个跨平台的用于并发通信的C++框架,项目开始时使用的是ACE 5.6发布版,目前最新的ACE版本是6.3.0. 网上一直有一种黑ACE的氛围,主要黑点在于ACE的复杂和作者的背景,结合实际应 ...

  4. ACE服务端编程5:ACE日志输出和跟踪

    服务器程序经常需要在命令行中显示错误消息.状态或者用来跟踪程序的执行路径,最简单的方法是使用printf. ACE提供了更强大日志设施: 1.可以在编译时启用或禁用宏: 2.可以动态的启用或禁用宏: ...

  5. Linux多线程服务端编程一些总结

    能接触这本书是因为上一个项目是用c++开发基于Linux的消息服务器,公司没有使用第三方的网络库,卷起袖子就开撸了.个人因为从业经验较短,主 要负责的是业务方面的编码.本着兴趣自己找了这本书.拿到书就 ...

  6. 《Linux 多线程服务端编程:使用 muduo C++ 网络库》电子版上市

    <Linux 多线程服务端编程:使用 muduo C++ 网络库> 电子版已在京东和亚马逊上市销售. 京东购买地址:http://e.jd.com/30149978.html 亚马逊Kin ...

  7. 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册

    <Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...

  8. 《Linux多线程服务端编程》笔记——多线程服务器的适用场合

    如果要在一台多核机器上提供一种服务或执行一个任务,可用的模式有 运行一个单线程的进程 运行一个多线程的进程 运行多个单线程的进程 运行多个多线程的进程 这些模式之间的比较已经是老生常谈,简单地总结 模 ...

  9. 《Linux多线程服务端编程》笔记——线程同步精要

    并发编程基本模型 message passing和shared memory. 线程同步的四项原则 尽量最低限度地共享对象,减少需要同步的场合.如果确实需要,优先考虑共享 immutable 对象. ...

随机推荐

  1. redis与mysql性能对比、redis缓存穿透、缓存雪崩

    写在开始 redis是一个基于内存hash结构的缓存型db.其优势在于速读写能力碾压mysql.由于其为基于内存的db所以存储数据量是受限的. redis性能 redis读写性能测试redis官网测试 ...

  2. WeakHashMap介绍

    WeakHashMap简介 WeakHashMap 继承于AbstractMap,实现了Map接口.    和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key ...

  3. php 中关于pdo的使用

    之前一段时间,开始了php的研究,看了关于PDO的一些资料,发现不错,整理和总结一下,作为开发笔记,留待日后使用,<PHP开发笔记系列(一)-PDO使用>. PDO是PHP Data Ob ...

  4. Scrum立会报告+燃尽图(Beta阶段第二周第七次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2415 项目地址:https://coding.net/u/wuyy694 ...

  5. 王者荣耀交流协会scrum立会20171111

    1.立会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:高远博 2.时间跨度: 2017年11月10日 18:00 - 18:33 ,总计33分钟. 3.地 点: 一 ...

  6. Python语言基础

    一.Python简介 Python是跨平台动态语言 特点:优雅.明确.简单 适用:web网站和网络服务:系统工具和脚步:包装其他语言开发的模块 不适用:贴近硬件(首选C):移动开发:IOS/Andro ...

  7. 《JavaScript》页面跳转

    window.location.href: <i onclick="window.location.href = '/Form/Form_Write/Index?viewname=Fo ...

  8. 关于解决乱码问题的一点探索之一(涉及utf-8和GBK)

    在使用Visual Studio 2005进行MFC开发的时候,发现自动添加的注释变成了乱码.像这样: // TODO: ÔÚ´ËÌí¼ÓרÓôúÂëºÍ/»òµ÷ÓûùÀà 还有这样: // ...

  9. 通过js读取元素的样式

    /* * 通过元素.style.样式只能获取到内联样式的值,就是style写在元素里面的值,不能获取嵌入式和外联样式的值 * 所以如果要获取除内联样式后的值,就不能通过这个获取 * alert(box ...

  10. Alpha冲刺阶段集合贴

    第一篇:http://www.cnblogs.com/xss6666/p/8870734.html 第二篇:http://www.cnblogs.com/xss6666/p/8893683.html ...