【问题标题】:How do I implement dynamic shared memory resizing?如何实现动态共享内存大小调整?
【发布时间】:2015-08-18 06:01:08
【问题描述】:

目前我使用 shm_open 来获取文件描述符,然后每当我想向共享内存添加新缓冲区时使用 ftruncate 和 mmap。每个缓冲区都单独用于自己的目的。

现在我需要做的是任意调整缓冲区大小。 并且 munmap 缓冲并稍后再次重用可用空间。

对于第一个问题,我能想出的唯一解决方案是:ftuncate(file_size + old_buffer_size + extra_size),mmap,将数据复制到新缓冲区,然后对原始数据进行 munmap。这对我来说看起来非常昂贵,可能有更好的方法。它还需要每次都删除原始缓冲区。

对于第二个问题,我什至没有糟糕的解决方案,我显然无法在每次删除缓冲区时移动内存。如果我跟踪空闲内存并尽可能使用它,它会减慢分配过程,并让我留下一些未使用的零碎。

我希望这不会太令人困惑。 谢谢

【问题讨论】:

  • 问题:您知道需要多少个缓冲区以及每个缓冲区的最大大小吗?我正在考虑具有预定义数量的缓冲区的预定义大小。您将如何管理这些“单独用于其自身目的的缓冲区”?预定义的缓冲区大小毕竟意味着没有碎片......
  • 缓冲区的数量和大小来自程序外部,所以我无法预测它们会是什么。
  • 听起来像是一个初始化的事情...延迟到您知道为止,这样可以省去很多麻烦。
  • 不,缓冲区在整个运行时被添加/删除和调整大小任意次数。
  • 你不知道最坏的情况吗?如果你这样做了,你应该为此而构建。

标签: c memory-management resize shared-memory mmap


【解决方案1】:

我为此目的编写了一个开源库: rszshm - resizable pointer-safe shared memory

从描述页面引用:

为了适应大小调整,rszshm 首先映射一个大型的私有 noreserve 地图。这用于声明地址范围。共享文件映射 然后覆盖跨度的开始。后来呼吁延长 映射覆盖更多的跨度。尝试延伸到结束之外 span 返回错误。

我通过在原始地址使用 MAP_FIXED 和新大小调用 mmap 来扩展映射。

【讨论】:

  • 该解决方案没有意义,因为从一开始,lib 占用的内存空间比所需的要大。调整大小只是返回预占用的内存
  • 较大的span不分配内存,只是声明地址。
  • 通过声明内存,声明的内存不能用于其他目的,对吧?从这个意义上说,它与分配保留内存的效果相同。
  • 申请地址与分配内存不同。
  • 很高兴知道,在制作更多 cmets 之前,让我先做一些研究以自我教育。谢谢
【解决方案2】:

据我所知,您需要扩大(或缩小)现有内存映射。 linux下共享内存作为文件实现,位于/dev/shm内存文件系统中。此文件中的所有操作都与常规文件(和文件描述符)相同。

如果您想扩大现有映射,首先使用 ftruncate 扩展文件大小(如您所写),然后使用 mremap 将映射扩展为请求的大小。

如果您存储指向该区域的指针,您可能需要更新这些指针,但首先尝试使用 0 标志调用。在这种情况下,系统会尝试将现有映射增加到请求的大小(如果与其他保留的内存区域没有冲突)并且指针保持有效。

如果前一个选项不可用,请使用 MREMAP_MAYMOVE 标志。在这种情况下,系统会重新映射到另一个位置,但大多数情况下它是有效完成的(系统没有应用副本。)然后更新指针。

收缩是相同的,但顺序相反。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多