进程间通信之共享内存的简单理解
2018-03-23 16:58
225 查看
之前的一个小需求:处于同一台电脑的进程A,要给进程B发数据。但是进程B的主窗口在创建时,没有指定类名,也没有指定窗口名,所以无法通过::FindWindow() + ::SendMessage的方式发WM_CopyData的消息。所以最后决定采用进程间通信的方式来解决。
模拟了一个服务端和一个客户端,2个进程间采用共享内存进行通信。
服务端:为了测试使用,所以写了一个死循环,用断点来控制每次写入的时间void CSharedMemoryMethod::ReadSharedMemoryDataProc(void* pParam)
{
string strMapName("ShareMemory"); // 内存映射对象名称
LPVOID pBuffer;
// 共享内存指针
// 首先试图打开一个命名的内存映射文件对象
HANDLE hMap;
string strComData("This is common data!"); // 共享内存中的数据
hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strMapName.c_str());
if (NULL == hMap)
{
// 打开失败,创建
hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
strComData.length()+1,
strMapName.c_str());
// 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
strcpy((char*)pBuffer, strComData.c_str());
//cout << "写入共享内存数据:" << (char *)pBuffer << endl;
}
while (true)
{
// 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据
strComData = "once agin";
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
strcpy((char*)pBuffer, strComData.c_str());
break;
}
//Sleep(5000);
// 解除文件映射,关闭内存映射文件对象句柄
::UnmapViewOfFile(pBuffer);
::CloseHandle(hMap);
system("pause");
}
客户端:
int CSharedMemoryMethod::example()
{
string strMapName("ShareMemory"); // 内存映射对象名称
string strComData("This is common data!"); // 共享内存中的数据
LPVOID pBuffer;
// 共享内存指针
// 首先试图打开一个命名的内存映射文件对象
HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strMapName.c_str());
if (NULL == hMap)
{
return 0;
}
while (TRUE)
{ // 打开成功,映射对象的一个视图,得到指向共享内存的指针,显示出里面的数据
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
cout << "读取共享内存数据:" << (char *)pBuffer << endl;
}
getchar(); // 注意,进程关闭后,所有句柄自动关闭,所以要在这里暂停
// 解除文件映射,关闭内存映射文件对象句柄
::UnmapViewOfFile(pBuffer);
::CloseHandle(hMap);
system("pause");
return 0;
}
最终效果:
1.
2.
结论:
1. 只要客户端或者服务端,任意一方不解除文件映射,客户端就能一直读取内存里的数据。
2. 服务端如果写入新的数据内容,旧内容会被覆盖,无论客户端是否解除映射,都会取到最新的数据。
同时,在这个需求中get到的新技能——HWND_BROADCAST 广播消息
向所有注册了这个消息的进程发送广播消息,解决了因无法获得其他进程窗口的句柄,而无法传递消息的问题。详情见下一篇文章。
HWND_BROADCAST广播消息
模拟了一个服务端和一个客户端,2个进程间采用共享内存进行通信。
服务端:为了测试使用,所以写了一个死循环,用断点来控制每次写入的时间void CSharedMemoryMethod::ReadSharedMemoryDataProc(void* pParam)
{
string strMapName("ShareMemory"); // 内存映射对象名称
LPVOID pBuffer;
// 共享内存指针
// 首先试图打开一个命名的内存映射文件对象
HANDLE hMap;
string strComData("This is common data!"); // 共享内存中的数据
hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strMapName.c_str());
if (NULL == hMap)
{
// 打开失败,创建
hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
strComData.length()+1,
strMapName.c_str());
// 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
strcpy((char*)pBuffer, strComData.c_str());
//cout << "写入共享内存数据:" << (char *)pBuffer << endl;
}
while (true)
{
// 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据
strComData = "once agin";
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
strcpy((char*)pBuffer, strComData.c_str());
break;
}
//Sleep(5000);
// 解除文件映射,关闭内存映射文件对象句柄
::UnmapViewOfFile(pBuffer);
::CloseHandle(hMap);
system("pause");
}
客户端:
int CSharedMemoryMethod::example()
{
string strMapName("ShareMemory"); // 内存映射对象名称
string strComData("This is common data!"); // 共享内存中的数据
LPVOID pBuffer;
// 共享内存指针
// 首先试图打开一个命名的内存映射文件对象
HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strMapName.c_str());
if (NULL == hMap)
{
return 0;
}
while (TRUE)
{ // 打开成功,映射对象的一个视图,得到指向共享内存的指针,显示出里面的数据
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
cout << "读取共享内存数据:" << (char *)pBuffer << endl;
}
getchar(); // 注意,进程关闭后,所有句柄自动关闭,所以要在这里暂停
// 解除文件映射,关闭内存映射文件对象句柄
::UnmapViewOfFile(pBuffer);
::CloseHandle(hMap);
system("pause");
return 0;
}
最终效果:
1.
2.
结论:
1. 只要客户端或者服务端,任意一方不解除文件映射,客户端就能一直读取内存里的数据。
2. 服务端如果写入新的数据内容,旧内容会被覆盖,无论客户端是否解除映射,都会取到最新的数据。
同时,在这个需求中get到的新技能——HWND_BROADCAST 广播消息
向所有注册了这个消息的进程发送广播消息,解决了因无法获得其他进程窗口的句柄,而无法传递消息的问题。详情见下一篇文章。
HWND_BROADCAST广播消息
相关文章推荐
- 深入理解Linux进程间通信(IPC)-- Posix共享内存
- 进程间通信系列 之 共享内存简单实例
- 进程间通信系列 之 共享内存简单实例
- 进程间通信(共享内存),五种通信方式简单总结
- 深入理解Linux进程间通信(IPC)-- 共享内存shared memory mmap
- Linux进程间通信源码剖析,共享内存(shmget()、shmat()、shmdt()及shmctl())
- Linux进程间通信源码剖析,共享内存(shmget函数详解)
- 【Linux】进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信----共享内存
- Linux环境进程间通信-共享内存
- linux-进程间通信-共享内存
- Linux进程间通信之共享内存
- 进程间通信IPC——共享内存
- 进程间通信3--共享内存
- linux进程间通信-------共享内存
- linux进程间通信-共享内存
- 进程间通信---共享内存
- Linux环境进程间通信: 共享内存
- 进程间通信(3)——共享内存和信号量