简体   繁体   English

如何在Windows下正确使用共享内存

[英]How to use shared memory correctly under windows

I'm kind of new to shared memory and i was searching for a working example, i managed to find only over MSDN 我是共享内存的新手,我在寻找一个有效的示例,我设法只在MSDN上找到了

On the first process i've declared my shared memory as following: 在第一个过程中,我声明了以下共享内存:

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);

and on the second process: 在第二个过程中:

HANDLE hFileMap = ::OpenFileMapping(FILE_MAP_READ, FALSE, strContentsSizeFileMap.c_str());
LPVOID pData = ::MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);

I know that once I'm done working on the mapView, i need to release it using ' UnmapViewOfFile() '. 我知道一旦完成mapView的工作,就需要使用' UnmapViewOfFile() '释放它。 My question is where exactly? 我的问题是到底在哪里?

  1. Parent Process? 父进程?
  2. Child Process 子进程
  3. Both? 都?

If it's on both, does the OS keep some reference count on the address before it's fully released? 如果两者都使用,那么操作系统在完全释放地址之前是否会在地址上保留一些引用计数?

From MSDN: 从MSDN:

It also decrements the share count of the corresponding physical page 它还会减少相应物理页面的共享计数

which got me a little bit confused regarding what im actually supposed to do. 这让我对我实际上应该做什么感到困惑。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537%28v=vs.85%29.aspx

CreateFileMapping function CreateFileMapping函数
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. MapViewOfFile和MapViewOfFileEx函数将文件视图映射到进程地址空间。
... ...
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 . 因此,要完全关闭文件映射对象,应用程序必须通过调用UnmapViewOfFile取消映射文件映射对象的所有映射视图,并通过调用CloseHandle关闭文件映射对象句柄 These functions can be called in any order. 可以按任何顺序调用这些功能。

So Process #1 creates a map object in the operating system . 因此,进程#1 在操作系统中创建了一个地图对象。 Then process #1 maps some part of that into it's own process memory. 然后,进程1将其中的一部分映射到它自己的进程内存中。
Process #2 gets a handle to the same operating system mapping object, and maps the same part or a different part of that into it's own memory. 进程2获取到同一操作系统映射对象的句柄,并将该对象的相同部分或不同部分映射到其自己的内存中。
When either process is finished, they call UnmapViewOfFile which removes the mapping from it's own process memory, and they call CloseHandle on their handle to the operating system map. 当任一进程完成时,他们调用UnmapViewOfFile ,从而从其自身的进程内存中删除映射,并在其对操作系统映射的CloseHandle上调用CloseHandle Windows handles are all effectively reference-counted, so when all processes that have a handle call CloseHandle , then the operating system automatically destroys the map object. Windows句柄均有效引用计数,因此,当所有具有句柄的进程都调用CloseHandle ,操作系统将自动销毁地图对象。

Note that this means if process #1 creates the mapping, uses the mapping, then closes it entirely, and then process #2 tries to open that mapping, process #2 will fail because the operating system deleted it when no processes had any handles. 请注意,这意味着如果进程#1创建了映射,使用了该映射,然后将其完全关闭,然后进程#2试图打开该映射,则进程#2将失败,因为在没有进程具有任何句柄的情况下,操作系统将其删除。 To work around this, create files in the filesystem to back your memory, which allows the memory to stick around between processes, until you delete the file. 要解决此问题,请在文件系统中创建文件以备份您的内存,这将使内存在进程之间徘徊,直到您删除文件为止。

Every process that calls MapViewOfFile should call UnmapViewOfFile when it is finished using the shared memory. 使用共享内存完成后,每个调用MapViewOfFile的进程都应调用UnmapViewOfFile。 That would typically be when the program is shutting down. 通常是在程序关闭时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM