我有一个C ++应用程序,它通过shmget(2)在Linux系统上分配共享内存。我存储在共享内存中的数据会定期增长,我想以类似于realloc()增长常规内存的方式调整共享内存的大小。有没有办法做到这一点?我在IBM的网站上找到了一个提到SHM_SIZE命令的文档,但Linux和BSD联机帮助页没有它,即使在特定于Linux的部分也是如此。
答案 0 :(得分:7)
简单回答:没有简单的方法。
原因很合乎逻辑。共享内存分别附加到每个进程的虚拟空间。每个进程都有自己的虚拟地址空间。每个进程都可以自由地将段附加到任何(不是字面意思,对齐设置一些限制)任意地址。系统如何保证,通过将区域扩展4MiB,该区段的每个“用户”将能够在相同的起始地址中匹配bigget块,其中较小的区段以前是哪个?
但你不应该放弃!你可以有创意。您可以想出有一个标头段,您可以在其中存储有关真实有效负载段的信息。您可以使每个进程遵守某些规则,例如:重新附加有效负载段,如其标题段中所述的ID与已知的不匹配。
建议:我怀疑你知道这一点,但是永远不会指向共享区域内的数据,只会偏移。
我希望你能利用我的胡言乱语。
答案 1 :(得分:0)
对我来说,你可以为自己的目的编写自己的内存管理器。这个概念非常简单:
N
字节; 2*N
大小分配新的共享内存块; 我担心我们与此无关。这就是std::vector
的实施方式。在大多数情况下,void *realloc()
将返回指向新内存块的指针(但不会返回扩展旧块)。
答案 2 :(得分:0)
在我看来, mremap 功能已实现,可以执行您想要的操作。 您只需要在参数上精确指定共享内存段的旧大小和新大小即可。而且,如果添加了标志MREMAP_MAYMOV,它允许在需要时移动共享内存段(即,如果仅在旧共享内存段之后没有足够的可用空间)。