11

我有一个 C++ 应用程序,它通过 shmget(2) 在 Linux 系统上分配共享内存。我存储在共享内存中的数据会定期增长,我想以类似于 realloc() 增长常规内存的方式调整共享内存的大小。有没有办法做到这一点?我在 IBM 的网站上找到了一个文档,其中提到了 SHM_SIZE 命令,但是 Linux 和 BSD 联机帮助页没有它,即使在 Linux 特定的部分中也是如此。

4

3 回答 3

9

简单的答案:没有简单的方法。

原因很合乎逻辑。共享内存被单独附加到每个进程的虚拟空间。每个进程都有自己的虚拟地址空间。每个进程都可以自由地将段附加到任意地址(不是字面意思,对齐设置了一些限制)。系统如何保证,例如通过将区域扩展 4MiB,该段的每个“用户”都能够在先前较小段所在的相同起始地址处安装 bigget 块?

但你不应该放弃!你可以有创意。您可以想出拥有一个标头段的想法,您可以在其中存储有关实际有效负载段的信息。您可以使每个进程都遵守一些规则,例如:当它的 id(如header segment中某处所述)与已知的不匹配时重新附加有效负载段。

建议:我怀疑你知道这一点,但永远不要在共享区域内保留指向数据的指针,只保留 offset

我希望你能利用我的胡言乱语。

于 2014-05-28T07:08:41.883 回答
1

在我看来,您可以为自己的目的编写自己的内存管理器。这个概念很简单:

  1. 您有一个大小为N字节的共享内存块;
  2. 根据大小分配新的共享内存块2*N
  3. 将内存从一个块复制到另一个块;
  4. 释放旧的共享内存块;
  5. 将#2-4 包装成一些例程并使用它;

恐怕我们与此无关。这是如何std::vector实现的。在void *realloc()大多数情况下,将返回指向新内存块的指针(而不是扩展的旧块)。

于 2014-03-24T19:11:16.150 回答
0

在我看来,函数mremap的实现是为了执行你想要的。您只需在参数中精确说明旧大小和共享内存段的新大小。如果您添加标志 MREMAP_MAYMOV,它允许在需要时移动共享内存段(即,如果在旧共享内存段之后没有足够的可用空间)。

查看手册页: http: //man7.org/linux/man-pages/man2/mremap.2.html

于 2018-07-13T13:11:10.483 回答