共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,一般会用信号量同步。
主要函数:
CreateFileMapping()创建一个文件映射
LPVOID MapViewOfFile( 创建映像对象的视图
HANDLE hFileMappingObject, 文件映射对象的句柄
DWORD dwDesiredAccess, 对文件映射对象的访问类型
DWORD dwFileOffsetHigh, 视图开始的文件偏移量的高阶DWORD。
DWORD dwFileOffsetLow, 视图要开始的文件偏移量的低阶DWORD
SIZE_T dwNumberOfBytesToMap ); 映射到视图的文件映射的字节数。如果为0,则从指定的偏移量扩展到文件映射的末尾
OpenFileMapping( ) 打开一个文件映射
UnmapViewOfFile() 关闭映射视图
CloseHandle() 关闭内存映射句柄句柄
一个简单的实例:
进程A:
#include <iostream>
#include <string>
#pragma warning( disable : 4996)
int main()
{
WCHAR FileMappingName[] = L"ShareMemory";//内存映射名称
char BufferData[] = "另一个进程,你好"; //共享内存数据
LPVOID Buffer; //共享内存指针
//创建一个映射对象
FileMappingHandle = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
1024,
FileMappingName
);
//std::cout << strlen(BufferData) + 1; strlen()直计算buffer里面的实际占用空间,char的/0他没计算。
//std::cout << sizeof(BufferData);
//创建映像视图
Buffer = MapViewOfFile(FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
//将共享的数据拷入共享内存
strcpy((char*)Buffer, BufferData);
printf("写入内存数据:%s\r\n", (char*)BufferData);
}
Sleep(20000);//这里拦住程序不让其退出,否则进程一旦退出则销毁所有句柄,共享的内存块也会没了
//解除文件映射,关闭内存映射句柄
UnmapViewOfFile(Buffer);
CloseHandle(FileMappingHandle);
return 0;
}
进程B:
#include <iostream>
#include <windows.h>
#include <string>
#pragma warning( disable : 4996)
int main()
{
WCHAR FileMappingName[] = L"ShareMemory";//内存映射名称
char BufferData[] = "This is a Demo!"; //共享内存数据
LPVOID Buffer; //共享内存指针
//打开一个文件映射对象
HANDLE FileMappingHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, FileMappingName);
if (!FileMappingHandle)
{
std::cout << "没有共享内存" << std::endl;
system("pause");
return 0;
}
else
{
std::cout << "发现共享内存,开始读取他的数据" << std::endl;
}
//创建映像对象的视图
Buffer = MapViewOfFile(FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
std::string str = (char*)Buffer;
std::cout << str << std::endl;
UnmapViewOfFile(Buffer); //关闭视图
CloseHandle(FileMappingHandle);//关闭句柄
system("pause");
return 0;
}
运行结果: