gpt4 book ai didi

C++ 无法在我的 Windows 应用程序中重写共享内存。它分配新的内存

转载 作者:太空宇宙 更新时间:2023-11-04 11:39:51 27 4
gpt4 key购买 nike

C++ 中的共享内存对我来说是新事物,仍在学习,现在我发现它并不像我预期的那样工作。我想实现名为 CharBuffer 的类,它通过 CreateFileMapping 和 MapViewOfFile 函数将 char 数组映射到共享内存:

HANDLE hBuffer = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shmBufferName); 
char * buffer = (char *) MapViewOfFile(hBuffer, FILE_MAP_ALL_ACCESS, 0, 0, size);

向缓冲区添加字节是通过调用 CharBuffer 函数“add”实现的:

void CharBuffer::add(char * data, size_t size) {
memcpy(&buffer[0], &data[0], size);
}

没有检查数据大小,但这没问题,这只是我使用共享内存学习的测试应用程序。没关系,我可以将字节添加到缓冲区或成功地从缓冲区读取 - 没有错误,没有问题。我正在使用 CharBuffer 的第一个实例来做这件事。

但现在我想用 CharBuffer 的 second 实例打开共享内存,并读取或重写共享内存中的数据。对于开放和 map 内存,我使用:

HANDLE hBuffer = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shmBufferName);
char * buffer = (char *) MapViewOfFile(hBuffer, FILE_MAP_ALL_ACCESS, 0, 0, size);

打开时没有错误。现在我要解决我的问题了。在第一个 实例中,我将 64 MB 复制到共享内存。当我尝试使用正确映射共享内存的 second 实例逐字节读取它们时(它打印数据正常)但是在资源监视器中我可以看到我有两倍的内存 - 128 MB。第一次添加数据后,内存占用 64 MB,但在通过第二个实例打印数据期间,内存增加了下一个 64 内存。

同样的问题是用second instance向内存写入数据。

我的目标是拥有有限的共享内存并由两个或多个 CharBuffer 实例使用它(读/写)。能否请您解释一下问题出在哪里或如何实现我想要的?

非常感谢。

最佳答案

我从未使用内存映射文件来降低内存消耗。我认为你的问题是 MapViewOfFile 总是返回指向唯一地址空间的指针,这将修改你页面文件中的相同页面。我试图在 MSDN 中找到证明这一点的证据,我只找到了这篇文章:

http://msdn.microsoft.com/en-us/library/ms810613.aspx

我想这解释了它:

As mentioned above, you can have multiple views of the same memory-mapped file, and they can overlap. But what about mapping two identical views of the same memory-mapped file? After learning how to unmap a view of a file, you could come to the conclusion that it would not be possible to have two identical views in a single process because their base address would be the same, and you wouldn't be able to distinguish between them. This is not true. Remember that the base address returned by either the MapViewOfFile or the MapViewOfFileEx function is not the base address of the file view. Rather, it is the base address in your process where the view begins. So mapping two identical views of the same memory-mapped file will produce two views having different base addresses, but nonetheless identical views of the same portion of the memory-mapped file.

The point of this little exercise is to emphasize that every view of a single memory-mapped file object is always mapped to a unique range of addresses in the process. The base address will be different for each view. For that reason the base address of a mapped view is all that is required to unmap the view.

因此 MapViewOfFile 将地址返回到内存,一旦提交将分配其自己的物理内存,这实际上会增加您的进程内存消耗 - 正如您所描述的。

[编辑]

实际上,我开始看到即使 MapViewOffFile 都将地址返回到唯一的虚拟地址空间,它们都由相同的物理 RAM 页支持。您可以在 Memory-Mapped Files and Coherence 中通过 c/c++ 在 Windows 中阅读此内容:

If multiple processes are mapping views of a single data file, the data is still coherent because there is still only one instance of each page of RAM within the data file—it's just that the pages of RAM are mapped into multiple process address spaces.

下面博客中的技巧也证明了这一点:

http://blogs.msdn.com/b/oldnewthing/archive/2003/10/07/55194.aspx

每次您访问文件 View 时,资源监视器都会向您显示内存消耗过高,这是因为它会显示工作集大小,据我所知,这可能会显示两次共享内存。

关于C++ 无法在我的 Windows 应用程序中重写共享内存。它分配新的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21785719/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com