windows 映射文件会释放内存吗_Windows系统共享内存管理

一 进程逻辑空间 物理空间

a7ec9757564a76b6f481b4f1fd5112d7.png
6cb63533528e09004d0a96cb058e8159.gif

如上图所示,每个进程都有自己的逻辑空间,这些逻辑空间,会被映射到具体的物理空间中。

每个进程的逻辑空间都是彼此隔离,相互独立不受干扰的。

但是他们都会被映射到同一个物理空间去,当其所映射的物理空间有重叠的时,这重叠的部分就共享了物理内存

二 共享内存关键问题

创建物理内存

将物理内存映射到进程空间

读写互斥控制

1)创建物理内存,获得物理内存资源句柄

比如 由A进程 负责创建共享内存

A: 进程创建完物理内存后,直接返回物理内存句柄

 // 创建共享文件句柄  HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // 物理文件句柄 NULL, // 默认安全级别 PAGE_READWRITE, // 可读可写 0, // 高位文件大小 BUF_SIZE, // 地位文件大小 L"ShareMemory" // 共享内存名称 );
6cb63533528e09004d0a96cb058e8159.gif

B:B进程通过共享内存的全局名字,来获得共享物理内存句柄

 // 打开共享的文件对象 HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,NULL,L"ShareMemory");
6cb63533528e09004d0a96cb058e8159.gif

2) 物理内存映射进程空间

各个进程都是通过这种方式, 将物理空间共享内存,映射到进程逻辑空间

 // 映射缓存区视图 , 得到指向共享内存的指针 LPVOID lpBase = MapViewOfFile( hMapFile, // 共享内存的句柄 FILE_MAP_ALL_ACCESS, // 可读写许可 0, 0, BUF_SIZE );
6cb63533528e09004d0a96cb058e8159.gif

3) 释放

进程退出时,要解除映射

// 解除文件映射

UnmapViewOfFile(lpBase);

// 关闭内存映射文件对象句柄

CloseHandle(hMapFile);

4)互斥控制

采用互斥量或信号的机制

互斥量机制

进程A: 创建互斥量mutex while(1) { 申请mutex; 处理C; 释放mutex; 其他操作; }
6cb63533528e09004d0a96cb058e8159.gif
进程B: while(1) { 申请mutex; 处理C; 释放mutex; 其他操作; }
6cb63533528e09004d0a96cb058e8159.gif

示例:

进程A

#include #include using namespace std;  int main(){// 若不存在名为"pmutex"的互斥量则创建它;否则获取其句柄 HANDLE hMutex = CreateMutex(NULL, false, "pmutex"); if(NULL == hMutex) { cout<
6cb63533528e09004d0a96cb058e8159.gif

进程B

#include #include using namespace std;  int main(){// 若不存在名为"pmutex"的互斥量则创建它;否则获取其句柄 HANDLE hMutex = CreateMutex(NULL, false, "pmutex"); if(NULL == hMutex) { cout<
6cb63533528e09004d0a96cb058e8159.gif

信号量机制:

进程A : 执行 写操作

进程A 执行写操作//等待其他进程读操作完毕WaitForSingleObject(m_memMng.m_hReadEvent, INFINITE); //重置写操作信号量ResetEvent(m_memMng.m_hWriteEvent);//执行写操作memcpy//写操作完毕,恢复信号量,使得其它进程可读SetEvent(m_memMng.m_hWriteEvent);
6cb63533528e09004d0a96cb058e8159.gif

进程B: 执行读操作

//进程B执行读操作//等待主进程写完毕WaitForSingleObject(m_memMng.m_hWriteEvent, INFINITE);//重置读信号量ResetEvent(m_memMng.m_hReadEvent);//读操作,将共享内存数据拷贝本地变量memcpy//读操作完毕,设置信号量信号SetEvent(m_memMng.m_hReadEvent);
6cb63533528e09004d0a96cb058e8159.gif

三 封装

应该有的成员变量:

1)创建物理内存、映射进程空间 管理

HANDLE hMapping_; 物理空间资源句柄

MappedView View_; 物理映射成进程空间的操作

int size_; 物理空间大小

std::wstring name_; 共享内存名字

2) 信号量控制管理

HANDLE m_hReadEvent;

HANDLE m_hWriteEvent;

操作方法:

1)创建

bool CreateFileMap(); //创建

bool OpenFileMap(); //已存在,则打开

bool MapView(bool bCanWrite = true); //映射进程空间

2)映射管理类

class MappedView{public:MappedView() : view_(NULL) {}~MappedView() { CloseView(); }bool MapView(SharedMemory *shared_memory, bool can_write);//MapViewOfFilevoid CloseView();char *view() { return view_; }private: char *view_=nullptr;};
6cb63533528e09004d0a96cb058e8159.gif

共享内存管理类

class SharedMemory{public:SharedMemory() : hMapping_(NULL) {size_ = 0;m_hReadEvent = NULL;m_hWriteEvent = NULL;}~SharedMemory() { Close();  if (m_hReadEvent) {CloseHandle(m_hReadEvent); }if (m_hWriteEvent)CloseHandle(m_hWriteEvent);};public://初始化bool InitReceiver(std::wstring name, std::wstring readName = L"ShareMemoryReadEvent
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值