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,后期有机会单独写出来。
记录,为更好的自己!
ACE服务端编程4:ACE跨平台之运行时初始化和关闭的更多相关文章
- ACE服务端编程3:ACE跨平台之分配堆内存
ACE服务端编程系列的第三篇,探究ACE解决不同编译器之间分配堆内存的差异. 在ACE的官方示例中会看到大量的ACE_NEW_RETURN,ACE_NEW这样的宏,这是ACE为了消除不同编译器编译的代 ...
- ACE服务端编程2:ACE跨平台之数据类型和宽字符
ACE网络库的主要优势之一就是跨平台,ACE提供了操作系统API和编译器级别的跨平台解决方法,使开发人员不用再去关心操作系统和编译器的差异,但因此也带来了ACE的复杂性. ACE网络库的组织结构主要分 ...
- ACE服务端编程1:使用VS2010编译ACE6.0及从ACE5.6升级的注意事项
ACE是一个跨平台的用于并发通信的C++框架,项目开始时使用的是ACE 5.6发布版,目前最新的ACE版本是6.3.0. 网上一直有一种黑ACE的氛围,主要黑点在于ACE的复杂和作者的背景,结合实际应 ...
- ACE服务端编程5:ACE日志输出和跟踪
服务器程序经常需要在命令行中显示错误消息.状态或者用来跟踪程序的执行路径,最简单的方法是使用printf. ACE提供了更强大日志设施: 1.可以在编译时启用或禁用宏: 2.可以动态的启用或禁用宏: ...
- Linux多线程服务端编程一些总结
能接触这本书是因为上一个项目是用c++开发基于Linux的消息服务器,公司没有使用第三方的网络库,卷起袖子就开撸了.个人因为从业经验较短,主 要负责的是业务方面的编码.本着兴趣自己找了这本书.拿到书就 ...
- 《Linux 多线程服务端编程:使用 muduo C++ 网络库》电子版上市
<Linux 多线程服务端编程:使用 muduo C++ 网络库> 电子版已在京东和亚马逊上市销售. 京东购买地址:http://e.jd.com/30149978.html 亚马逊Kin ...
- 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册
<Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...
- 《Linux多线程服务端编程》笔记——多线程服务器的适用场合
如果要在一台多核机器上提供一种服务或执行一个任务,可用的模式有 运行一个单线程的进程 运行一个多线程的进程 运行多个单线程的进程 运行多个多线程的进程 这些模式之间的比较已经是老生常谈,简单地总结 模 ...
- 《Linux多线程服务端编程》笔记——线程同步精要
并发编程基本模型 message passing和shared memory. 线程同步的四项原则 尽量最低限度地共享对象,减少需要同步的场合.如果确实需要,优先考虑共享 immutable 对象. ...
随机推荐
- HTML(1)简介
"超"文本标记语言--HTML 文本,是指书面语言的表现形式. 百度百科 说白了,文本就是你能看得到的字,不论是纸上的还是屏幕上的,都是文本.文本就是用来记录信息一种形式. 那么, ...
- spark的数据结构 RDD——DataFrame——DataSet区别
转载自:http://blog.csdn.net/wo334499/article/details/51689549 RDD 优点: 编译时类型安全 编译时就能检查出类型错误 面向对象的编程风格 直接 ...
- “Hello World!”团队第六周的第二次会议
今天是我们团队“Hello World!”团队第六周召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码 一 ...
- Android 6.0 中的 Wifi 连接
Android 6.0 中的 Wifi 连接 这几天在写一个软件,结果被其中的 wifi 连接问题困扰了 3 天. 先描述下需求: usb 接口接了一根 usb2serial,通过这个接口接收命令 当 ...
- KNN算法之图像处理二
1.看了诸多博客,初步得到结论是:KNN不适合做图像分类. 2.如果偏要用此方法进行图像分类,距离计算为:对应的每个像素代表的像素值进行绝对差值计算,最后求和.这就是“图像的距离”
- C#高级编程 (第六版) 学习 第二章:C#基础
第二章 基础 1,helloworld示例: helloworld.cs using System; using System.Collections.Generic; using System.Li ...
- iOS- 如何建立索引实现本地文本搜索引擎,允许容错搜索?
1.前言 实现一个本地搜索引擎,允许容错搜索,也就是搜索结果不需要和搜索的关键字完全精准匹配.比如,搜索”eric wang“,搜索结果可以包括Erica Watts等等.搜索效率十分高. 这里我们需 ...
- iOS- Autolayout自动布局
1.前言 •在iOS程序中,大部分视图控制器都包含了大量的代码用于设置UI布局,设置控件的水平或垂直位置,以确保组件在不同版本的iOS中都能得到合理的布局 •甚至有些程序员希望在不同的设备使用相同的视 ...
- Swift-自定义类的构造函数
构造函数类似oc中的init方法默认情况下,创建一个,类会调用一个构造函数即使没写任何构造函数,编译器会默认一个构造函数如果是继承NSObject,可以对构造函数重写 class Person: NS ...
- 团队作业05——测试与发布(alpha阶段)
测试 请根据团队项目中软件的需求文档.功能说明.系统设计和测试计划,写出软件的测试过程和测试结果,并回答下述问题. 在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? 显示计算结果超过看 ...