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 对象. ...
随机推荐
- 239. [LeetCode ]Sliding Window Maximum
Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...
- Python 并行分布式框架:Celery 超详细介绍
本博客摘自:http://blog.csdn.net/liuxiaochen123/article/details/47981111 先来一张图,这是在网上最多的一张Celery的图了,确实描述的非常 ...
- 关于在eclipse Oxygen 2017环境下spring3.2 asm的异常
今天在oxygen 2017下构建spring3.2+mybatis项目时,发生异常,大概是说无法解析我mapper.class文件,错误发生在core.asm中<unknow:source&g ...
- 面试Tips
面试Tips 面向对象:准备找工作的同学 内容概述:关于面试的一些经验总结,希望能带给你些许帮助.若有描述不准确的地方,欢迎指点建议. 内容提炼:共分为四阶段 1.面试前之静生慧 (1)课本知识过一遍 ...
- emacs编译整个emacs.d目录
$emacs 在emacs查看里面,输入: C-u M-x byte-recompile-directory 然后输入 ~/.emacs.d 即可.
- 1029对c语言文法的理解
<程序>→<外部声明>|<程序><外部声明> <外部声明>→<函数定义>|<声明> <函数定义>→< ...
- 【第二周】【作业五】Scrum 每日站会
1.首先来看一下什么是Scrum: Scrum是一种敏捷软件开发的方法学,用于迭代式增量软件开发过程.Scrum在英语是橄榄球运动中争球的意思. 虽然Scrum是为管理软件开发项目而开发的,它同样可以 ...
- HDU 2132 An easy problem
http://acm.hdu.edu.cn/showproblem.php?pid=2132 Problem Description We once did a lot of recursional ...
- windows平台下nginx+PHP环境安装
因为日常工作在windows下,为方便在window是下进行PHP开发,需要在windows平台下搭建PHP开发环境,web服务器选择nginx,不过windows版本的nginx性能要比Linux/ ...
- PHP执行原理
简单解释:PHP执行原理 客户端向服务器发送一个请求,如果请求的是一个HTML页面,服务器直接将HTML页面发送到客户端给浏览器解析,如果请求的是PHP页面,则服务器会运行PHP页面然后生成标准的HT ...