应用文件映射进行进程间通讯
来源:互联网 发布:伴生活智能门禁 知乎 编辑:程序博客网 时间:2024/06/03 13:18
文件映射解释:
(摘抄)内存映射文件用来保留一个地址空间,并提交物理存储器。早期的内存映射文件并不是提交物理内存供调用者使用,而是提交永久存储器(外存)上的文件数据。当然操作系统会为永久存储器保留一个读缓冲区,这样读取文件数据就快多了。内存映射文件的特点使它很适合于加载EXE或DLL文件。这样可以节省内存又减少了加载所需时间。还可以使用它来映射大容量的文件,这样就不必在读取文件数据前设置很大的缓冲区。另外内存映射文件常用于进程间通信,也是进程间通信的主要手段,其它进程之间通信机制都是基于内存映射文件来实现。为了更快的在进程之间通信,现在的内存映射文件也可以提交物理内存,这样内存映射文件既可以提交物理内存又可以提交文件
应用文件映射进行进程间通信
原来来内存映射文件只映射类似磁盘一类的存储器上的文件。而为了更快速地在进程之间通信,内存映射文件还可以提交物理内存。实现方法是通过访问同一个内存映射文件对象(映射到物理内存),两个进程或多个进程就能够访问到同一块物理内存设进程。
假设进程A和进程B需要通信,那么进程A需要先创建一个内存映射文件(之前不必调用CreateFileForMapping函数来创建文件,因为不需要创建文件)。这个内存映射文件可以是在永久存储器中,也可以是在内存中。为了减小通信时间,最好提交物理内存。
1.进程A在调用CreateFileMapping函数时,参数1指定为INVALID_HANDLE_VALUE,这表示这个内存映射文件对象将要把物理内存提交到地址空间中。最后一个参数一定要指定一个名字。
2.进程B也同样调用CreateFileMapping函数,而且参数相同。内核会根据名字来判断是否已经存在一个内存映射文件对象,如果创建了就返回原来的对象的句柄。
3.获得地址空间指针
MapViewOfFile()
如果需要进行文件写入, 可以通过类型转换直接对于内存地址进行赋值, 比如: memcpy( lpAddress, lpBuf, ....) 如果是读取操作, 将参数顺序调整一下
4.卸载内存映射文件地址指针
UnmapViewOffFile()
5.关闭内存映射文件
CloseHandle()
下面这个例子写进程加载一个位图并将数据写到内存映射文件中,读进程从内存映射文件读取数据并生成新位图。
写进程:
#include "stdafx.h"#include <iostream>#include <Windows.h>#include "FileHandler.h"using namespace std;typedef struct{long size;long bufferAdd;}SharedData;SharedData *lpData ;HANDLE hMemoryMap;void FreeMemory(){if(lpData){::UnmapViewOfFile(lpData);lpData=NULL;}if(hMemoryMap){CloseHandle(hMemoryMap);hMemoryMap = NULL;}}BYTE* CAlloc(WCHAR* name, long size){FreeMemory();BYTE* addr;hMemoryMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, size, name);if (hMemoryMap != NULL){addr = (BYTE *)MapViewOfFile(hMemoryMap, FILE_MAP_WRITE, 0, 0, 0);if (addr == NULL){CloseHandle(hMemoryMap);hMemoryMap = NULL;return NULL;}if(IsBadWritePtr(addr,size)!=FALSE){::UnmapViewOfFile(addr);addr = NULL;::CloseHandle(hMemoryMap);hMemoryMap = NULL;}}return addr;}int _tmain(int argc, _TCHAR* argv[]){hMemoryMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 64, L"DataMap");if (hMemoryMap != NULL){lpData = (SharedData *)MapViewOfFile(hMemoryMap, FILE_MAP_WRITE, 0, 0, 0);if (lpData == NULL){CloseHandle(hMemoryMap);hMemoryMap = NULL;}}FileHandler *h=new FileHandler;FileInfo file=h->ReadFile("file/Butterfly2.bmp");lpData =(SharedData *)CAlloc( L"DataMap",sizeof(long)*2+file.size);lpData->size=file.size;lpData->bufferAdd=(long)(lpData+sizeof(long)*2);void * dst=(void *)(lpData+sizeof(long)*2);memcpy(dst,file.buffer,file.size); delete file.buffer; file.buffer=NULL; std::cout<<"\nwaiting......."; Sleep(-1); return 0;}
读进程:
#include "stdafx.h"#include <iostream>#include <Windows.h>#include "FileHandler.h"using namespace std;typedef struct{ long size; long bufferAdd;}SharedInData;int _tmain(int argc, _TCHAR* argv[]){ SharedInData *lpData ; HANDLE hMemoryMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 4096, L"DataMap"); if (hMemoryMap != NULL) { lpData =(SharedInData *) MapViewOfFile(hMemoryMap, FILE_MAP_READ, 0, 0, 0); if (lpData == NULL) { CloseHandle(hMemoryMap); hMemoryMap = NULL; } } FileHandler *file=new FileHandler; file->WriteFile("bitmap.bmp",(char*)lpData->bufferAdd,lpData->size); Sleep(-1); return 0;}
文件处理类
#include "stdafx.h"#include "FileHandler.h"using namespace std;/*************************************************************************//*ofstream: 写操作(输出)的文件类 (由ostream引申而来) /*ifstream: 读操作(输入)的文件类(由istream引申而来) /*fstream: 可同时读写操作的文件类 (由iostream引申而来) ios::in 为输入(读)而打开文件 ios::out 为输出(写)而打开文件 ios::ate 初始位置:文件尾 ios::app 所有输出附加在文件末尾 ios::trunc 如果文件已存在则先删除该文件 ios::binary 二进制方式 seekg ( off_type offset, seekdir direction );seekp ( off_type offset, seekdir direction );使用这个原型可以指定由参数direction决定的一个具体的指针开始计算的一个位移(offset)。它可以是:ios::beg 从流开始位置计算的位移 ios::cur 从流指针当前位置开始计算的位移 ios::end 从流末尾处开始计算的位移 /*************************************************************************/FileHandler::FileHandler(){}FileHandler::~FileHandler(){}FileInfo FileHandler::ReadFile(char* filename){FileInfo info;char * buffer; long size; ifstream file (filename, ios::in|ios::binary|ios::ate); size = file.tellg(); file.seekg (0, ios::beg); buffer = new char [size]; file.read (buffer, size); file.close(); info.size=size;info.buffer=buffer;//buffer[size]='\0';cout << "the complete file is in a buffer:"<<size; return info;}bool FileHandler::WriteFile(char* filename,char * buffer,int length){ofstream file (filename, ios::out|ios::binary|ios::trunc); file.write(buffer,length);file.close();return true;}long FileHandler::GetFileSize(char* filename){int size=0;ifstream file (filename, ios::in|ios::binary|ios::ate); size = file.tellg(); file.close(); return size;}
- 应用文件映射进行进程间通讯
- 内存映射文件 进程间通讯
- 进程间通讯——内存映射/文件映射形式
- 进程间通讯(五)--共享内存(文件映射)
- windows进程间通讯--文件映射(FileMapping)
- 使用内存映射文件实现进程通讯
- 内存映射文件夸进程通讯 a和b通讯
- 内存映射文件的方式进行进程间通信
- 内存映射文件的方式进行进程间通信
- 【IPC进程间通讯之三】内存映射文件Mapping File
- .NET 4.0中使用内存映射文件实现进程通讯
- .NET 4.0中使用内存映射文件实现进程通讯
- .NET 4.0中使用内存映射文件实现进程通讯
- .NET 4.0中使用内存映射文件实现进程通讯
- 使用注册消息进行进程间通讯
- .NET多进程间进行互相通讯
- 内存映射实现进程通讯
- linux应用编程----进程间通讯kill
- 完整的rac带dataguard实验
- Flex mxmlc编译命令选项
- delphi 遍历文件算法(含遍历目录算法)
- 走进新浪微博的真实世界
- XE5安卓手机要求
- 应用文件映射进行进程间通讯
- Linux screen命令
- 在Android中afinal框架下实现sqlite数据库版本升级的办法
- 5、AOP原理
- flex 正则表达式对空字符串的诡异判断
- 忘记顺序了
- active dg实验
- 英语学习五大法则
- Flex之旅:第一部分:flex必备基础知识积累(4)---ArrayCollection, Array赋值写法