如何在窗口下正确使用共享内存
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()
"发布它。我的问题是到底在哪里?
- 父进程?
- 子进程
- 双?
如果两者兼而有之,操作系统在完全发布地址之前是否保留了一些引用计数?
从 MSDN:
它还会减少相应物理页的共享计数
这让我对我实际上应该做什么有点困惑。
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx
创建文件映射函数
为指定文件创建或打开命名或未命名的文件映射对象。
...
创建文件映射对象实际上不会将视图映射到进程地址空间。MapViewOfFile 和 MapViewOfFileEx 函数将文件的视图映射到进程地址空间中。
...
文件映射对象的映射视图维护对该对象的内部引用,并且在释放对文件映射对象的所有引用之前,不会关闭该文件映射对象。因此,若要完全关闭文件映射对象,应用程序必须通过调用 UnmapViewOfFile 取消映射文件映射对象的所有映射视图,并通过调用 CloseHandle 关闭文件映射对象句柄。可以按任意顺序调用这些函数。
因此,进程 #1 在操作系统中创建一个映射对象。 然后进程 #1 将其的一部分映射到它自己的进程内存中。
进程 #2 获取同一操作系统映射对象的句柄,并将其中的相同部分或不同部分映射到其自己的内存中。
当任一进程完成后,它们调用UnmapViewOfFile
,这会从其自己的进程内存中删除映射,并在操作系统映射的句柄上调用CloseHandle
。 Windows 句柄都是有效的引用计数,因此当具有句柄调用的所有进程都CloseHandle
时,操作系统会自动销毁映射对象。
请注意,这意味着如果进程 #1 创建映射,使用该映射,然后完全关闭它,然后进程 #2 尝试打开该映射,则进程 #2 将失败,因为操作系统在没有进程没有任何句柄时将其删除。 若要解决此问题,请在文件系统中创建文件来备份内存,这允许内存在进程之间保留,直到删除文件。
每个调用 MapViewOfFile 的进程都应该在使用完共享内存后调用 UnmapViewOfFile。这通常是在程序关闭时。
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 字符串共享内存映射的向量
- CUDA 使用共享内存平铺 3D 卷积实现
- 共享内存:MapViewOfFile 返回错误 5
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- 有没有办法列出所有共享内存对象的名称?
- 共享内存的升压容器是否实现锁定?
- 共享内存中的健壮互斥锁不是那么健壮
- 使用IPC/共享内存将Integer数组从C++传递到Python
- 共享内存和性能
- 在这种特殊情况下,我是否需要在共享内存中使用原子类型
- 是否可以在专用内存空间中分配一个为提升管理共享内存而创建的对象
- fork(),在C中共享内存和指针
- 访问共享内存而不使用易失性、std::atomic、信号量、互斥锁和自旋锁
- 提升进程间共享内存open_or_create每次都会引发异常
- 通过 mmap-ed 共享内存传递可变长度 C 字符串
- 越界访问 CUDA 共享内存
- 在共享内存中插入映射映射时出现编译器错误
- 矩阵矢量产品 CUDA 通过平铺和共享内存提高性能
- 如何更改在 c++ 中使用提升库创建的共享内存的路径