windows下如何正确使用共享内存
How to use shared memory correctly under windows
我是共享内存的新手,我正在寻找一个工作示例,我设法找到了超过 MSDN
在第一个进程中,我声明了我的共享内存如下:
hFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, dwDataSize, strSharedMemoryName.c_str());
pBuffer = ::MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, dwDataSize);
::CopyMemory(pBuffer, pData, dwDataSize);
在第二个过程中:
HANDLE hFileMap = ::OpenFileMapping(FILE_MAP_READ, FALSE, strContentsSizeFileMap.c_str());
LPVOID pData = ::MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
我知道在完成 mapView 的工作后,我需要使用“UnmapViewOfFile()
”发布它。我的问题是具体在哪里?
- 父进程?
- 子进程
- 两者都有?
如果两者都存在,OS 是否会在地址完全释放之前保留一些引用计数?
来自 MSDN:
It also decrements the share count of the corresponding physical page
这让我对我实际应该做什么感到有点困惑。
每个调用 MapViewOfFile 的进程在使用完共享内存后都应该调用 UnmapViewOfFile。这通常是在程序关闭时。
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx
CreateFileMapping function
Creates or opens a named or unnamed file mapping object for a specified file.
...
Creating a file mapping object does not actually map the view into a process address space. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process address space.
...
Mapped views of a file mapping object maintain internal references to the object, and a file mapping object does not close until all references to it are released. Therefore, to fully close a file mapping object, an application must unmap all mapped views of the file mapping object by calling UnmapViewOfFile and close the file mapping object handle by calling CloseHandle. These functions can be called in any order.
因此进程 #1 在操作系统中创建了一个映射对象。然后进程 #1 将其中的一部分映射到它自己的进程内存中。
进程 #2 获取同一操作系统映射对象的句柄,并将其相同部分或不同部分映射到它自己的内存中。
当任一进程完成时,他们调用 UnmapViewOfFile
从它自己的进程内存中删除映射,然后他们在操作系统映射的句柄上调用 CloseHandle
。 Windows 句柄都是有效的引用计数,所以当所有拥有句柄的进程调用 CloseHandle
时,操作系统会自动销毁映射对象。
请注意,这意味着如果进程 #1 创建映射,使用映射,然后完全关闭它,然后进程 #2 尝试打开该映射,进程 #2 将失败,因为操作系统在没有打开映射时将其删除进程有任何句柄。要解决此问题,请在文件系统中创建文件以备份您的内存,这允许内存在进程之间停留,直到您删除文件。
我是共享内存的新手,我正在寻找一个工作示例,我设法找到了超过 MSDN
在第一个进程中,我声明了我的共享内存如下:
hFileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, dwDataSize, strSharedMemoryName.c_str());
pBuffer = ::MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, dwDataSize);
::CopyMemory(pBuffer, pData, dwDataSize);
在第二个过程中:
HANDLE hFileMap = ::OpenFileMapping(FILE_MAP_READ, FALSE, strContentsSizeFileMap.c_str());
LPVOID pData = ::MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
我知道在完成 mapView 的工作后,我需要使用“UnmapViewOfFile()
”发布它。我的问题是具体在哪里?
- 父进程?
- 子进程
- 两者都有?
如果两者都存在,OS 是否会在地址完全释放之前保留一些引用计数?
来自 MSDN:
It also decrements the share count of the corresponding physical page
这让我对我实际应该做什么感到有点困惑。
每个调用 MapViewOfFile 的进程在使用完共享内存后都应该调用 UnmapViewOfFile。这通常是在程序关闭时。
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx
CreateFileMapping function
Creates or opens a named or unnamed file mapping object for a specified file.
...
Creating a file mapping object does not actually map the view into a process address space. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process address space.
...
Mapped views of a file mapping object maintain internal references to the object, and a file mapping object does not close until all references to it are released. Therefore, to fully close a file mapping object, an application must unmap all mapped views of the file mapping object by calling UnmapViewOfFile and close the file mapping object handle by calling CloseHandle. These functions can be called in any order.
因此进程 #1 在操作系统中创建了一个映射对象。然后进程 #1 将其中的一部分映射到它自己的进程内存中。
进程 #2 获取同一操作系统映射对象的句柄,并将其相同部分或不同部分映射到它自己的内存中。
当任一进程完成时,他们调用 UnmapViewOfFile
从它自己的进程内存中删除映射,然后他们在操作系统映射的句柄上调用 CloseHandle
。 Windows 句柄都是有效的引用计数,所以当所有拥有句柄的进程调用 CloseHandle
时,操作系统会自动销毁映射对象。
请注意,这意味着如果进程 #1 创建映射,使用映射,然后完全关闭它,然后进程 #2 尝试打开该映射,进程 #2 将失败,因为操作系统在没有打开映射时将其删除进程有任何句柄。要解决此问题,请在文件系统中创建文件以备份您的内存,这允许内存在进程之间停留,直到您删除文件。