Windows共享内存以及相关函数的使用
2015-01-29 10:49
155 查看
程序与程序之间、进程与进程之间、线程与线程之间进行数据交互与共享的方法是决定一个程序运行效率与速度的关键。
方法1:共享内存函数 CreateFileMapping
1) 物理文件句柄
任何可以获得的物理文件句柄, 如果你需要创建一个物理文件无关的内存映射也无妨, 将它设置成0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.
如果需要和物理文件关联, 要确保你的物理文件创建的时候的访问模式和"保护设置"匹配, 比如: 物理文件只读, 内存映射需要读写就会发生错误. 推荐你的物理文件使用独占方式创建.
如果使用 INVALID_HANDLE_VALUE, 也需要设置需要申请的内存空间的大小, 无论物理文件句柄参数是否有效, 这样 CreateFileMapping 就可以创建一个和物理文件大小无关的内存空间给你, 甚至超过实际文件大小, 如果你的物理文件有效, 而大小参数为0,
则返回给你的是一个和物理文件大小一样的内存空间地址范围. 返回给你的文件映射地址空间是可以通过复制, 集成或者命名得到, 初始内容为0.
2) 保护设置
就是安全设置, 不过一般设置NULL就可以了, 使用默认的安全配置. 在win2k下如果需要进行限制, 这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是, 可以考虑进行限制.
3) 高位文件大小
弟兄们, 我想目前我们的机器都是32位的东东, 不可能得到超过32位进程所能寻址的私有32位地址空间, 一般还是设置0吧, 我没有也不想尝试将它设置超过0的情况.
4) 低位文件大小
这个还是可以进行设置的, 不过为了让其他共享用户知道你申请的文件映射的相关信息, 我使用的时候是在获得的地址空间头部添加一个结构化描述信息, 记录内存映射的大小, 名称等, 这样实际申请的空间就比输入的增加了一个头信息结构大小了, 我认为这样类似BSTR的方式应该是比较合理的.
5) 共享内存名称
MapViewOfFile 函数用来映射对象视图
一旦其他进程获得映射对象的句柄,可以象创建进程那样调用MapViewOfFile函数来映射对象视图。用户可以使用该对象视图来进行数据读写操作,以达到数据通讯的目的。
当用户进程结束使用共享内存后,调用UnmapViewOfFile函数以取消其地址空间内的视图:
MapViewOfFile函数返回一个指向文件视图的指针。利用MapViewOfFile中声明的地址指针,程序就可以从文件中读以及向文件中写入数据。向文件视图中写入数据会导致文件映射对象改变。真正将数据写入到磁盘上的文件,由系统负责处理。数据并不是马上就别写到磁盘上,很多文件的输入输出都被缓存起来,以改善系统的性能。程序可以调用FlushViewOfFile函数来越过这个方式,强迫系统马上将数据写入到磁盘中去。
程序实例
创建共享内存区域:
在另一个程序中读取这一块共享区域:
方法1:共享内存函数 CreateFileMapping
HANDLE CreateFileMapping(
HANDLE hFile, //物理文件句柄
LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
DWORD flProtect, //保护设置
DWORD dwMaximumSizeHigh, //高位文件大小
DWORD dwMaximumSizeLow, //低位文件大小
LPCTSTR lpName //共享内存名称
);
参数解释
1) 物理文件句柄
任何可以获得的物理文件句柄, 如果你需要创建一个物理文件无关的内存映射也无妨, 将它设置成0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.
如果需要和物理文件关联, 要确保你的物理文件创建的时候的访问模式和"保护设置"匹配, 比如: 物理文件只读, 内存映射需要读写就会发生错误. 推荐你的物理文件使用独占方式创建.
如果使用 INVALID_HANDLE_VALUE, 也需要设置需要申请的内存空间的大小, 无论物理文件句柄参数是否有效, 这样 CreateFileMapping 就可以创建一个和物理文件大小无关的内存空间给你, 甚至超过实际文件大小, 如果你的物理文件有效, 而大小参数为0,
则返回给你的是一个和物理文件大小一样的内存空间地址范围. 返回给你的文件映射地址空间是可以通过复制, 集成或者命名得到, 初始内容为0.
2) 保护设置
就是安全设置, 不过一般设置NULL就可以了, 使用默认的安全配置. 在win2k下如果需要进行限制, 这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是, 可以考虑进行限制.
3) 高位文件大小
弟兄们, 我想目前我们的机器都是32位的东东, 不可能得到超过32位进程所能寻址的私有32位地址空间, 一般还是设置0吧, 我没有也不想尝试将它设置超过0的情况.
4) 低位文件大小
这个还是可以进行设置的, 不过为了让其他共享用户知道你申请的文件映射的相关信息, 我使用的时候是在获得的地址空间头部添加一个结构化描述信息, 记录内存映射的大小, 名称等, 这样实际申请的空间就比输入的增加了一个头信息结构大小了, 我认为这样类似BSTR的方式应该是比较合理的.
5) 共享内存名称
MapViewOfFile 函数用来映射对象视图
LPVOID MapViewOfFile(
HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap);
一旦其他进程获得映射对象的句柄,可以象创建进程那样调用MapViewOfFile函数来映射对象视图。用户可以使用该对象视图来进行数据读写操作,以达到数据通讯的目的。
当用户进程结束使用共享内存后,调用UnmapViewOfFile函数以取消其地址空间内的视图:
if (!UnmapViewOfFile(pszMySharedMapView))
{
AfxMessageBox("could not unmap view of file");
}
MapViewOfFile函数返回一个指向文件视图的指针。利用MapViewOfFile中声明的地址指针,程序就可以从文件中读以及向文件中写入数据。向文件视图中写入数据会导致文件映射对象改变。真正将数据写入到磁盘上的文件,由系统负责处理。数据并不是马上就别写到磁盘上,很多文件的输入输出都被缓存起来,以改善系统的性能。程序可以调用FlushViewOfFile函数来越过这个方式,强迫系统马上将数据写入到磁盘中去。
程序实例
创建共享内存区域:
#include "stdafx.h" HANDLE m_hMapFile; int _tmain(int argc, _TCHAR* argv[]) { //m_hMapFile = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,1024,_T("TestFileMap")); m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("TestFileMap")); for(;;) { //创建共享文件。 m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL, PAGE_READWRITE,0,1024,_T("TestFileMap")); //拷贝数据到共享文件里。 LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS, 0,0,0); //CString strTest(_T("TestFileMap")); wcscpy(lpMapAddr,_T("I am the public memory in the disk!")); FlushViewOfFile(lpMapAddr,sizeof(_T("TestFileMap"))+1); } return 0; }
在另一个程序中读取这一块共享区域:
#include "stdafx.h" HANDLE m_hMapFile; int _tmain(int argc, _TCHAR* argv[]) { m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,_T("TestFileMap")); LPTSTR lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS, 0,0,0); OutputDebugString(lpMapAddr); return 0; }
相关文章推荐
- 2440中UART的使用以及相关函数详解
- 3.QT中的debug相关的函数,以及文件锁的使用
- 2440中UART的使用以及相关函数详解
- Qt中窗体最大最小化以及窗口大小修改的相关函数使用(2)
- C++中结构体、联合、枚举的使用以及函数相关
- 3.QT中的debug相关的函数,以及文件锁的使用
- C#之中SqlCommand以及相关函数的使用
- 在LoadRunner中使用文件的相关函数
- javascript入门系列演示·函数的定义以及简单参数使用,调用函数
- javascript入门系列演示·函数的定义以及简单参数使用,调用函数
- java中yield(),sleep()以及wait()的区别往往混淆了这三个函数的使用。
- 自己写感觉比较好且使用的的函数 包括浏览目录以及 Slplit函数
- Windows Mobile开发中Visual Studio以及相关工具的使用
- JavaScript的相关继承笔记以及使用外部库实现JavaScript的面向对象特性
- Delphi中用来截取字符的函数,以及使用方法?
- SWFUpload简介以及相关使用
- glib中g_object_set_data及相关函数的使用[0713]
- javascript入门系列演示·函数的定义以及简单参数使用,调用函数
- 线程函数的设计以及MsgWaitForMultipleObjects函数的使用要点
- 使用单独的命令处理类来处理命令消息(适用于有很多命令处理函数的对象,以及共享命令处理函数)