ACE的全称是自适应通信环境(ADAPTIVE Communication
Environment),ADAPTIVE又是 A Dynamically Assembled Protocol
Transformation, Integration, and eValuation Environment
的缩写。历史悠久,甚至比GNU还久远。
ACE大量运用设计模式,很好的包装的网络通信的全部细节,消弭各种操作系统之间的差异,也提供了完整的接口保证足够的灵活性,并且大量运用模板等C++的高级特性,保证了效率(通用的东西往往效率低,ACE是否的确没有比原生代码损失效率这个有待进一步证实)。
ACE提供的全部的源代码,可以在各种平台下编译。
ACE中最主要的几个东西:
1。Reactor
反应式多路分离器,向它注册一些事件及相应的Handler,当事件发生时它会调用相应的Handler,这个比较容易理解也比较容易使用。就好像Select然后根据不同的事件调用不同的函数。其本质是Reactor告诉你何时可做何事,接下来你执行操作。
2。Proactor前摄式多路分离器,异步I/O模式,用法是发起一个操作,等操作完成了Proactor告诉你。Windows下的完成端口就是这样一种模式,事实上ACE在Windows上实现的Proactor就是用的完成端口。这个看得比较少,目前还没有详细了解。
3。Task
这个东西很难用一个明确的中文来准确完整的表达,它封装了线程和线程池,完全隔离了各平台原生线程的差异,有一个svc函数,相当于原生线程里面的线程函数。
4。Message_Block,消息块,包含一个数据块和一个计数的指针引用,合理使用既能很好的封装数据又能方便使用,还能避免不必要的数据拷贝。
5。MessageQueue,消息队列,提供了一个线程安全的消息队列
6。ACE_OS里面提供了不少有用的函数和宏,掩盖系统之间的差异。
例如ACE_DEBUG提供了类似于MFC中的TRACE的功能
ACE_OS::gettimeofday()返回当前时间,类似于linux中的gettimeofday()和windows下的gettickcount()
这个编译错误是因为 _WIN32_WINNT
这个宏的值设置得过低了,
可以在编译选项中的预处理器定义中加入_WIN32_WINNT=0x0500
其实在使用ACE的时候总是先包含ACE的头文件就不会出现这个问题了。
另外如果项目有预编译头文件,不妨把ACE的头文件放到stdafx.h中
recv和accept问题不大,可操作才会去操作,不会阻塞
send则可能陷入阻塞,因此可以设置一个超时。
另一个方案是对可用的线程数计数,当可用的线程数量少到一定程度时,
做一些调整(添加新的线程或者减短超时)。
这个计数需要是线程安全的,如果代价太大就不值得了
幸运的是 在大多数机器体系结构上,对基本类型的改变都是原子的。(参见 《ACE 程序员指南》p227)
我们可以对Reactor通知事件,ACE_Reactor::instance()->notify( handler, mask)
ACE有一个类包装了这个这种调用 ACE_Reactor_Notification_Strategy
另外ACE_Message_Queue自带一个通知对象指针,可以为它指定一个上面的对象
则在有ACE_Message_Block进入ACE_Message_Queue时,会自动调用notify
发起反应器的事件。这种方法用在发送数据上非常方便。