内存映射文件
多个操作系统平台都提供了内存映射文件,这是一个简单的将数据结构保存到文件中的机制。同时由于32位操作系统的进程虚拟内存最大只能4GB,用内存映射文件的方式就可以突破这个限制,可以用来打开超过4GB的大文件。
而且,内存映射文件其实就是一种共享内存机制,进程间可以通过共享内存直接访问数据。
ACE提供了ACE_MMAP_Memory_Pool类,该类代表了为内存映射文件分配内存的内存池。和ACE_Malloc模板类配合,我们就可以以平台无关的方式操纵内存映射文件了。比如:ACE_Malloc<ACE_MMAP_Memory_Pool,ACE_SYNCH_MUTEX> 。第二个参数是并发锁的策略类。
下面的例子实现了write函数,该函数负责将结构SHMRecord的数据写到内存映射文件snapshot中,并且以HashMap的方式保存。key是offset的字符串表示,value是结构的指针。
注意,结构中的pData_成员指向的内存也应该由ACE_Malloc在内存映射文件中分配。这种模式下,千万用常规思路管理内存回收,比如智能指针,有时候内存不需要回收。
#include <iostream>
#include <sstream>
using namespace std;
#include "ace/MMAP_Memory_Pool.h"
#include "ace/Malloc_T.h"
class SHMRecord
{
public:
SHMRecord():pData_(NULL){}
ACE_UINT16 type_;
ACE_UINT32 offset_;
void* pData_;
ACE_UINT32 dataLength_;
size_t size() const
{
return 2+4+4+dataLength_;
}
};
typedef
ACE_Malloc<ACE_MMAP_Memory_Pool,ACE_SYNCH_MUTEX> MAllocator;
void write()
{
MAllocator allocator("/opt/ace/freebird/snapshot");
void * pMemory=allocator.malloc(sizeof(SHMRecord));
if(pMemory==NULL)
{
cout<<"malloc failed"<<endl;
return;
}
SHMRecord* pRecord=new(pMemory) SHMRecord();
pRecord->type_=9;
pRecord->offset_=2;
pRecord->dataLength_=4;
pRecord->pData_=allocator.malloc(4);
ACE_OS::strcpy(static_cast<char*>(pRecord->pData_),"hel");
stringstream stream;
stream<<pRecord->offset_;
if(allocator.bind(stream.str().c_str(),pRecord)==-1)
{
cout<<"bind failed"<<endl;
return;
}
allocator.sync();
}
void read()
{
}
int main(void)
{
write();
read();
return 0;
}
ACE_Malloc模板类的malloc成员负责分配内存,free负责释放内存,bind负责将数据添加到HashMap中,sync负责将数据从内存写到文件中。构造函数接收文件名作为参数。
现在我们来完成read函数,该函数将负责从内存映射文件中读取数据,并且显示出来。
void read()
{
MAllocator allocator("/opt/ace/freebird/snapshot");
ACE_Malloc_LIFO_Iterator<ACE_MMAP_Memory_Pool,ACE_SYNCH_MUTEX> iter(allocator);
for(void* pData=0;iter.next(pData)!=0;iter.advance())
{
SHMRecord* pRecord=ACE_reinterpret_cast(SHMRecord*,pData);
cout<<pRecord->type_<<endl;
cout<<pRecord->offset_<<endl;
cout<<static_cast<char*>(pRecord->pData_)<<endl;
cout<<pRecord->dataLength_<<endl;
}
}
这里使用了一个后进先出的迭代器,可以遍历HashMap中的数据。当然也可以使用find方法查找指定的数据。
多个进程因而可以使用同一块共享内存,但是问题是这些内存在每个进程中的基地址可能不同。虽然大多数操作系统能够保证,但是万一遇到意外情况怎么办?在这种情况下直接保存的指针将毫无意义。
ACE提供了解决方案:
1)使用ACE_Malloc_T<ACE_MMAP_MEMORY_POOL,
ACE_NUll_Mutex,ACE_PI_Control_Block>代替前面的分配器。关键在于ACE_PI_Control_Block类,该类使我们获得了于位置无关的分配内存功能。
2)在我们的结构中使用了普通的C++指针,现在要替换成ACE_Based_Pointer_Basic<char>类型。 该类会针对不同的基地址重新计算指针。
3)迭代器也应该使用父类:
ACE_Malloc_LIFO_Iterator_T<ACE_MMAP_Memory_Pool,ACE_SYNCH_MUTEX,ACE_PI_Control_Block> iter(allocator);
分享到:
相关推荐
ace开源码
ACE共享内存 code demo,你懂的。。
ACE 共享内存,满足进程间数据交互需求。
ACE自适配通信环境(Adaptive Communication Environment)是一种面向对象(OO)的工具包,它实现了通信软件的许多基本的设计模式。ACE的目标用户是在UNIX和Win32平台上开发高性能通信服务和应用的开发者。ACE简化了...
ACE_Allocator,ACE中的分配器类的接口类;...ACE_Cached_Allocator,预先分配内存池,其中含有特定数目和大小的内存chunk;ACE_New_Allocator,为C++ new和delete操作符提供包装的分配器,内部使用new和delete操作符
ACE进程算法技术
ace技术内幕实例代码
详细的描述了ACE框架,大量的案例和源码实验有助于快速掌握整个前端框架
《ace技术内幕:深入解析ace架构设计与实现原理》从构架模式、编程示例和源代码3个维度系统地对经典网络框架ace(adaptivemunicationenvironment)的架构设计和实现原理进行了深入分析,它能解决4个方面的问题:,...
美国ACE缓冲器技术样本pdf,美国ACE缓冲器技术样本
ACE提供了一组丰富的可复用C++ Wrapper Facade(包装外观)和框架组件,可跨越多种平台完成通用的通信软件任务,其中包括:事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息...
上中下三篇 上篇:ACE技术论文集.pdf 下篇:ACE应用实例.pdf 中篇:ACE程序员教程.pdf
ACE自适配通信环境中文技术文档完整版,包含代序、ACE技术论文集、ACE程序员指南、ACE应用实例。共601页。
ace技术内幕一书的示例代码-linux平台
ACE技术论文集、自适配通信环境、应用实例及开发教程等资料: ACE自适配通信环境(代序).pdf ACE详细介绍译文.pdf 上篇:ACE技术论文集.pdf 下篇:ACE应用实例.pdf 中篇:ACE程序员教程.pdf 译者说明.pdf
上篇:ACE技术论文集.pdf
ACE自适配通信环境中文技术文档_中篇ACE程序员教程.pdf
ACE自适配通信环境(Adaptive Communication Environment)是一种面向对象(OO)的工具包,它实现了通信软件的许多基本的设计模式。ACE的目标用户是在UNIX和Win32平台上开发高性能通信服务和应用的开发者。ACE简化了...
ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南ace起步指南