IPC进程间通信+共享内存Mapping
IPC(Inter-Process Communication,进程间通信)。
文件映射(Mapping)是一种将文件内容映射到内存地址的技术,通过对映射内存,读写文件如同读写内存一般简单。
多个进程映射同一个文件映射对象,也即多个进程映射到同一个物理存储页面,因此,当一个进程向映射内存写入数据时,其他进程可以通过映射内存读取数据,通过这个机制实现进程间通信。
1.内存文件映射Mapping File :
A进程创建一个命名的Mapping对象,并在映射内存中写入需要共享的数据。B进程通过对象名打开Mapping对象,映射该Mapping对象,从映射内存中读取数据。
2.基本API函数 :
创建Mapping对象:
HANDLE CreateFileMapping(
HANDLE hFile, //物理文件句柄
LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
DWORD flProtect, //保护设置
DWORD dwMaximumSizeHigh, //高位文件大小
DWORD dwMaximumSizeLow, //低位文件大小
LPCTSTR lpName //共享内存名称
);
HANDLE hFile, //物理文件句柄
LPSECURITY_ATTRIBUTES lpAttributes, //安全设置
DWORD flProtect, //保护设置
DWORD dwMaximumSizeHigh, //高位文件大小
DWORD dwMaximumSizeLow, //低位文件大小
LPCTSTR lpName //共享内存名称
);
该函数返回创建的Mapping对象。
创建映射内存:
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, //Mapping对象
DWORD dwDesiredAccess, //存取类别
DWORD dwFileOffsetHigh, //映射文件高位
DWORD dwFileOffsetLow, //映射文件地位
SIZE_T dwNumberOfBytesToMap //映射字节数
);
HANDLE hFileMappingObject, //Mapping对象
DWORD dwDesiredAccess, //存取类别
DWORD dwFileOffsetHigh, //映射文件高位
DWORD dwFileOffsetLow, //映射文件地位
SIZE_T dwNumberOfBytesToMap //映射字节数
);
该函数用于创建Mapping对象的映射内存,返回映射内存。
内存复制:
VOID CopyMemory(
PVOID Destination, //要复制内存块的目的地址
CONST VOID *Source, //要复制内存块的源地址
SIZE_T Length //复制的字节数
);
PVOID Destination, //要复制内存块的目的地址
CONST VOID *Source, //要复制内存块的源地址
SIZE_T Length //复制的字节数
);
该函数用于将数据复制到映射内存。
打开Mapping对象:
HANDLE OpenFileMapping(
DWORD dwDesiredAccess , // 存取权限
BOOL bInheritHandle , //继承设置,一般设为FALSE
LPCTSTR lpName // Mapping对象名
);
DWORD dwDesiredAccess , // 存取权限
BOOL bInheritHandle , //继承设置,一般设为FALSE
LPCTSTR lpName // Mapping对象名
);
该函数用于打开一个存在的Mapping对象。返回Mapping对象句柄。
3.牛刀小试:
先在VC6.0中运行process1程序,在运行process2程序:
运行效果:
process1程序:
#include
#include
#include
void main()
{
char szName[]="共享内存示例!";
char szMsg[]="Hello Mapping!";
//文件映射句柄
HANDLE hMapFile;
//共享数据缓冲区指针
LPTSTR pBuf;
//创建命名的文件映射,不代表任务硬盘上的文件
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
256,
szName);
//创建映射内存
pBuf = (LPTSTR) MapViewOfFile(hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
256);
//将共享数据复制到文件映射中
CopyMemory((PVOID)pBuf, szMsg, strlen(szMsg));
printf("共享内存建立完成,按任意键取消共享内 存并退出!\n");
getch();
//取消映射,退出
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
}
process2 程序:
#include
#include
#include
/* 预处理申明*/
#pragma comment (lib, "User32.lib")
#define BUF_SIZE 256
/* 全局变量 */
TCHAR szName[]=TEXT("共享内存示例!");
void main()
{
HANDLE hMapFile;
LPTSTR pBuf;
//打开文件mapping
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS,
FALSE,
szName);
if (hMapFile == NULL)
{
printf("OpenFileMapping error: %d.\n", GetLastError());
return;
}
//映射
pBuf = MapViewOfFile(hMapFile,
FILE_MAP_ALL_ACCESS,
0,
0,
256);
if (pBuf == NULL)
{
printf("MapViewOfFile error %d\n", GetLastError());
return;
}
//消息得到的共享数据
printf("共享内存数据: %s\n",pBuf);
//取消mapping,关闭句柄,返回
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
}