C/C++ 日常学习总结(第二十二篇)共享内存实现C++
2014-09-23 14:11
597 查看
大家都知道进程之间的通信可以使用共享内存,但是在具体代码中如何实现呢?下面就介绍下操作原理和我自己的实现代码。
在linux下使用的是shmget,shmat,shmdt等函数,所以在网上看到这类的,基本就是在介绍linux环境下的实现,windows下不适用,但可以看其原理。
0.传输数据的结构定义
上面结构的定义较为简单,仅为了测试使用。
1.我们会创建两个程序,一个称之服务端,一个称之客户端。
服务端:(1.)创建共享内存区域 (2.)内存映射到当前进程 (3.)写入数据
客户端:(1.)打开共享内存区域 (2.)内存映射到当前进程 (4.)读出数据
2.服务端
(1)、创建一个特定大小的文件映射对象,名称为“GameQueen”,也可以宏来定义。
(2)、将这个对象的文件视图映射到进程的地址空间,然后向视图中写入数据/字符串。
(3)、函数参数分析
3.客户端
源码:
过程分析:
(1.)执行客户程序CMyShareClientDlg
(2.)打开这个名称为“GameQueen”的文件映射对象
(3.)然后把相同的文件映射视图映射到自己的地址空间中
(4.)然后从视图中读取服务进程所写入的数据。
4.截图
服务端发送数据:
客户端接收数据:
5.注意
(1.)由于事件,信号,互斥对象和文件映射等这些内核对象都共享同一个名字空间,所以如果这个名字和其他一个对象的名称重名的话那么将创建失败。
(2.)为了实现共享内存,进程应首先调用CreateFileMapping函数然后在hFile参数中传入INVALID_HANDLE_VALUE宏来替代句柄。相应的文件映射对象会从系统的分页文件中获得一段内存。如果hFile参数的值是INVALID_HANDLE_VALUE,那么你在调用CreateFileMapping时必须给共享内存指定一个大小值。
在linux下使用的是shmget,shmat,shmdt等函数,所以在网上看到这类的,基本就是在介绍linux环境下的实现,windows下不适用,但可以看其原理。
0.传输数据的结构定义
struct Splayer { int numid; int age; char sex; char name[128]; char ip[256]; int port; };
上面结构的定义较为简单,仅为了测试使用。
1.我们会创建两个程序,一个称之服务端,一个称之客户端。
服务端:(1.)创建共享内存区域 (2.)内存映射到当前进程 (3.)写入数据
客户端:(1.)打开共享内存区域 (2.)内存映射到当前进程 (4.)读出数据
2.服务端
void CMySharedServerDlg::MySharedMemory()上面是源码,简诉下过程:
{
/*
struct Splayer { int numid; int age; char sex; char name[128]; char ip[256]; int port; };
*/
//1.创建共享内存区域
HANDLE hfile = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,65536,"GameQueen");
if(NULL==hfile)
{
AfxMessageBox("创建失败!",MB_OK,0);
return;
}
//2.内存映射
PVOID pview = NULL;
pview = ::MapViewOfFile(hfile,FILE_MAP_ALL_ACCESS,0,0,1024);
if (NULL==pview)
{
AfxMessageBox("映射失败!",MB_OK,0);
return;
}
//char* pMessage = "皇后come from MySharedServerDlg!";//单独字符串也可传输
Splayer player;
player.numid = 6666;
player.age = 24;
player.sex = '1';
strcpy(player.name,"tangwei");
strcpy(player.ip,"192.168.1.102");
player.port = 8080;
DWORD dmessage = sizeof(Splayer);
memcpy_s(pview,1024,&player,dmessage);
}
(1)、创建一个特定大小的文件映射对象,名称为“GameQueen”,也可以宏来定义。
(2)、将这个对象的文件视图映射到进程的地址空间,然后向视图中写入数据/字符串。
(3)、函数参数分析
// Create the file mapping object. hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // Use paging file - shared memory NULL, // Default security attributes PAGE_READWRITE, // Allow read and write access 0, // High-order DWORD of file mapping max size MAP_SIZE, // Low-order DWORD of file mapping max size FULL_MAP_NAME // Name of the file mapping object );
pView = MapViewOfFile( hMapFile, // Handle of the map object FILE_MAP_ALL_ACCESS, // Read and write access 0, // High-order DWORD of the file offset VIEW_OFFSET, // Low-order DWORD of the file offset VIEW_SIZE // The number of bytes to map to view );
3.客户端
源码:
void CMyShareClientDlg::MySharedMemory() { HANDLE hfile = OpenFileMapping(FILE_MAP_READ,FALSE,"GameQueen"); if (NULL==hfile) { AfxMessageBox("不能打开共享内存",MB_OK,0); return; } PVOID pview; pview = ::MapViewOfFile(hfile,FILE_MAP_READ,0,0,1024); if (NULL==pview) { AfxMessageBox("不能打开2",MB_OK,0); return; } //char* pStr = (char*)pview; //CString str(pStr); //OutputDebugString(str); Splayer *player = (Splayer*)pview;//上面读取字符串,此处是读取结构体信息 }
过程分析:
(1.)执行客户程序CMyShareClientDlg
(2.)打开这个名称为“GameQueen”的文件映射对象
(3.)然后把相同的文件映射视图映射到自己的地址空间中
(4.)然后从视图中读取服务进程所写入的数据。
4.截图
服务端发送数据:
客户端接收数据:
5.注意
(1.)由于事件,信号,互斥对象和文件映射等这些内核对象都共享同一个名字空间,所以如果这个名字和其他一个对象的名称重名的话那么将创建失败。
(2.)为了实现共享内存,进程应首先调用CreateFileMapping函数然后在hFile参数中传入INVALID_HANDLE_VALUE宏来替代句柄。相应的文件映射对象会从系统的分页文件中获得一段内存。如果hFile参数的值是INVALID_HANDLE_VALUE,那么你在调用CreateFileMapping时必须给共享内存指定一个大小值。
相关文章推荐
- C/C++日常学习总结(第十篇)string的实现&文件流操作
- C/C++ 日常学习总结(第二十篇)实现自己的printf函数
- 多线程实现资源共享的问题学习与总结
- C\C++指针(地址)学习总结(附内存分配方式)
- spark学习七 共享内存的实现(快速的共享数据)
- C/C++日常学习总结(第十七篇)#define XNAME(n) x##n
- C/C++日常学习总结(第十五篇)逻辑运算符对于负数的处理
- C++学习总结_成员函数的声明和实现需要注意问题
- C/C++日常学习总结(第七篇)常引用&指针的理解
- C/C++日常学习总结(第十二篇)将构造函数声明为explicit(显式)的方式可以抑制隐式转换
- C/C++日常学习总结(第九篇)三次握手&为什么加extern “C”
- C/C++日常学习总结(第十六篇)分析IA-64和IA-32位机器上同一个程序运行,前者报错,后者正常
- C++学习- C++中的类所占内存空间总结
- C/C++日常学习总结(第一篇)const用法及printf的执行顺序
- C/C++日常学习总结(第十三篇)默认构造函数内部再调用带参的构造函数
- UNIX环境高级编程学习之第十五章进程间通信 - 两个进程通过映射普通文件实现共享内存通信
- Windows共享内存 C++及C#实现
- C/C++日常学习总结(第三篇)不能重载的运算符和不同基类继承产生的二义性
- C/C++日常学习总结(第四篇)共同基类产生的二义性和继承与组合的区别
- 多线程实现资源共享的问题学习与总结