我可以用shmctl调整Linux共享内存的大小吗?

时间:2013-05-07 16:12:48

标签: c++ linux shared-memory

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

3 个答案:

答案 0 :(得分:7)

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

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

但你不应该放弃!你可以有创意。您可以想出有一个标头段,您可以在其中存储有关真实有效负载段的信息。您可以使每个进程遵守某些规则,例如:重新附加有效负载段,如其标题段中所述的ID与已知的不匹配。

建议:我怀疑你知道这一点,但是永远不会指向共享区域内的数据,只会偏移

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

答案 1 :(得分:0)

对我来说,你可以为自己的目的编写自己的内存管理器。这个概念非常简单:

  1. 您有一个共享内存块,其大小为N字节;
  2. 使用2*N大小分配新的共享内存块;
  3. 将内存从一个块复制到另一个块;
  4. 释放旧的共享内存块;
  5. 将#2-4包装成一些常规并使用它;
  6. 我担心我们与此无关。这就是std::vector的实施方式。在大多数情况下,void *realloc()将返回指向新内存块的指针(但不会返回扩展旧块)。

答案 2 :(得分:0)

在我看来, mremap 功能已实现,可以执行您想要的操作。 您只需要在参数上精确指定共享内存段的旧大小和新大小即可。而且,如果添加了标志MREMAP_MAYMOV,它允许在需要时移动共享内存段(即,如果仅在旧共享内存段之后没有足够的可用空间)。

查看联机帮助页:http://man7.org/linux/man-pages/man2/mremap.2.html