ACE内存映射技术

news/2024/7/7 15:25:45
 

内存映射文件

多个操作系统平台都提供了内存映射文件,这是一个简单的将数据结构保存到文件中的机制。同时由于32位操作系统的进程虚拟内存最大只能4GB,用内存映射文件的方式就可以突破这个限制,可以用来打开超过4GB的大文件。

而且,内存映射文件其实就是一种共享内存机制,进程间可以通过共享内存直接访问数据。

ACE提供了ACE_MMAP_Memory_Pool类,该类代表了为内存映射文件分配内存的内存池。和ACE_Malloc模板类配合,我们就可以以平台无关的方式操纵内存映射文件了。比如:ACE_Malloc<ACE_MMAP_Memory_Pool,ACE_SYNCH_MUTEX> 。第二个参数是并发锁的策略类。

下面的例子实现了write函数,该函数负责将结构SHMRecord的数据写到内存映射文件snapshot中,并且以HashMap的方式保存。keyoffset的字符串表示,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);

转载于:https://www.cnblogs.com/believeit/archive/2008/08/22/2183603.html


http://www.niftyadmin.cn/n/4820568.html

相关文章

征服Python—语言基础与典型应用

书名&#xff1a; 征服Python—语言基础与典型应用 出版社&#xff1a;人民邮电出版社作者&#xff1a;孙广磊出版日期&#xff1a;2007年9月版次&#xff1a;第1版ISBN&#xff1a;978-7-115-216657-9/TP定价&#xff1a;59.00元 想读&#xff1a; <script src"htt…

SecureCRT 与Linux基本命令介绍

SecureCRT SecureCRT是常用得瑟终端仿真程序&#xff0c;就是windows下登陆Linux或Unix服务器主机的软件 SecureCRT的安装教程大家可以百度&#xff0c;就不详细描述了&#xff0c;可以参考http://jingyan.baidu.com/article/49ad8bce69ad285834d8fa9a.html Linux基础命令的…

VC调用.dll文件

调用的原理&#xff1a; 调用DLL&#xff0c;首先需要将DLL文件映像到用户进程的地址空间中&#xff0c;然后才能进行函数调用&#xff0c;这个函数和进程内部一般函数的调用方法相同。Windows提供了两种将DLL映像到进程地址空间的方法&#xff1a;隐式调用&#xff08;通过lib…

8.1.3 在Python扩展中使用MFC

8.1.3 在Python扩展中使用MFC 作者: 孙广磊 出处:人民邮电出版社 ( ) 砖 ( ) 好 评论 ( ) 条  进入论坛 更新时间&#xff1a;2007-10-16 14:15关 键 词&#xff1a;Python MFC GUI 编程 函数 Windows 征服Python—语言基础与典型应用阅读提示&#xff1a;《征服Py…

Gradle之多渠道打包

多渠道打包 所谓多渠道打包&#xff0c;实际上是在代码层面上标记不同的渠道名&#xff0c;从而便于统计应用市场apk的下载量&#xff0c; 利用Gradle进行多渠道打包&#xff0c;开发者从之前的ant打包中解放出来&#xff0c;Gradle进行简单多了&#xff0c;只需要在Gradle脚…

QT实践

这两天工作搞了下QT&#xff0c;主要是为了实现一个功能&#xff0c;跨平台用的。功能是这样的&#xff0c;根据一个页面表单进行选择元素最后生成一个xml文件发送到手机上&#xff0c;因为之前实现了xmpp发送文件的作用&#xff0c;所以现在只需要根据文件生成一个xml文件。中…

[游戏]五子连珠

五子连珠是 一个同色相消类游戏。你可以移动小球&#xff0c; 使其从一个位置移动到另外一个位置&#xff0c;尽量使同一颜色的小球排成一横行、竖行或者斜行。只要在这些行上的小球达到5个或者多于5个&#xff0c;这些球就可以消去。直达 棋盘上没有空格放置小球时&#xff0c…

Python扩展方法及工具比较

http://zfqcn.blog.163.com/blog/static/2280681200711111311923/一、普通扩展方法 扩展Python包括三个步骤&#xff1a;1. 创建源程序(C, C, java, ...)&#xff1b;2. 为源程序写wrap代码&#xff1b; 包括四个步骤&#xff1a;? include "Python.h";? 为每…