正在寻找C++中基于Windows RAM的共享内存解决方案

looking for Windows RAM-based shared memory solution in C++

本文关键字:RAM 共享 内存 解决方案 Windows 寻找 C++      更新时间:2023-10-16

我面临的情况是,我需要将数百兆字节的内存从一个进程传递到另一个进程。现在我是通过文件完成的,速度太慢了。我想,为了更快,这些文件应该直接写入RAM,并且可以从另一个进程访问。不需要花哨的同步。一个进程将创建共享内存对象,并用数据填充它们。另一个过程将读取并删除它们。然而,我做了一个快速的研究,似乎你不能在Windows的RAM中共享内存——共享内存由文件或分页文件支持。boost::interprocess的文档证实了这一点。如果共享内存实现仍然使用磁盘,那么速度在哪里?有没有使用基于RAM的共享内存的C++库?

编辑:我做了一些进一步的阅读:1.来自boost::进程间文档:由于操作系统必须将文件内容与内存内容同步,内存映射文件不如共享内存快2.来自http://msdn.microsoft.com/en-us/library/ms810613.aspx:"一个内存映射文件也可以由多个应用程序同时映射。这是两个或多个进程在Windows NT中直接共享数据的唯一机制。"

p>我认为这是一个根本性的误解:你认为,如果你创建一个由分页文件支持的文件映射,它将像在磁盘上实际写入东西一样慢。

事实并非如此:文档中"由分页文件支持"的含义意味着共享内存通常位于内存中,但如果没有足够的可用物理内存,并且虚拟内存管理器需要交换内存页面,则共享内存在分页文件中有一个保留位置来写入此类数据。

这一点从文档中并不清楚,但MSDN上的文件映射页面证实:

[…]它由磁盘上的文件支持。这意味着当系统交换文件映射对象的页面时,对文件映射对象所做的任何更改都会写入文件。当文件映射对象的页面交换回时,它们将从文件中恢复。

请注意,这适用于由分页文件支持的共享内存以及由常规文件支持的内存(VMM保证各种视图保持一致)。

顺便说一句,用户进程中的"常规"(=虚拟)内存就是这样工作的:如果当前没有使用,则分配的每一位内存都可以交换到页面文件中,并且系统需要将物理内存用于其他内容(例如,使您/另一个应用程序可以使用当前使用的内存页面)。

由文件备份没有错——在内存压力下,数据必须放在某个地方,您的选择是:

  • 将内存视为神圣的数据,不能分页或丢弃

    可能只会造成更严重的内存压力问题,但对于一些嵌入式系统来说,这是一个很好的选择,因为系统的整个运行时环境可以得到很好的控制。

  • 丢弃存储器

    显然不适用于所有数据。缓存的内容?大概原始照片?可能不会。

  • 将内存分页到磁盘

    很好的通用选择!

使用共享内存工具时,您是否看到内存压力?添加更多RAM或找出如何缩小系统。:)

据我所知,这里基本上有两个选项。

1) 创建一个DLL并使用data_seg杂注,然后在两个进程中加载该DLL。这有巨大的缺点,这里将详细解释:http://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.80).aspx

最重要的缺点是:空间必须静态初始化,并存储在编译后的DLL的数据段中,这意味着如果你想使用这种方法共享数百MB,那么你的DLL将有数百MB大。

2) 使用常规内存映射文件并没有错,因为它们无论如何都是缓存的。您甚至可以使用系统页面文件来存储数据,如本文所述:http://msdn.microsoft.com/en-us/library/ms810613.aspx

我实际测试了进程间通信的示例[1]使用1GIB内存映射文件,即使在用数据填充整个GiB后,也可以确认没有任何内容写入磁盘。

[1]http://msdn.microsoft.com/en-us/library/aa366551(v=vs.85).aspx

我仍然建议使用内存映射文件,而不是我将要提到的方法。

如果确实要从另一个进程内存中读取,请使用Win32 API ReadProcessMemory()。

如果你偏执于将数据保存在RAM中,那么在MS Windows VirtualLock()中有Unix mlock()等价物