2017-04-03 47 views
1

我的问题是关于使用Boost.Interprocess,在单个写入器进程和多个读取器进程的上下文中增加内存映射区域。 使用作者的managed_mapped_file::grow是否可以,假设读者不需要更新地图尺寸的更改是可以接受的?我的假设是,读者的地图将保持有效,然后当我需要他们从作者处获取最新更改时,我可以用更新的大小重新映射读者。它是否正确?Growing Boost.Interprocess内存映射文件与单个写入器

文档的Growing managed segments部分表示:

一旦管理的段中创建管理的段不能生长。这个限制并不容易解决:每个连接到被管理部分的进程都需要停止,并通知新的大小,他们需要重新映射被管理部分并继续工作。 [...]

这让我觉得我可以grow只要我很好,读者不马上更新。然而,文件继续说:

另一方面,Boost.Interprocess提供离线分段增长。这是什么意思?如果没有进程映射受管段,则可以扩展段。如果应用程序可以找到一个没有附加进程的时刻,它可以增长或缩小以适应被管理的细分市场。 managed_mapped_file也提供了类似的功能来增长或管理文件。请记住,在执行增长/缩小过程时,不应该修改文件/共享内存。否则,被管段将被损坏。

这让我觉得我不能做我想做的事,但我不明白为什么它不起作用。

+0

你想谈谈一些关于细分管理员与共享内存的更多宠物吗?我还有几个警告,你可能想知道做出设计决定:) – sehe

+0

是的,我非常想知道这些警告。 –

+0

[过来](https://chat.stackoverflow.com/rooms/10/loungec)如果你有时间 – sehe

回答

0

让我们shared_memory_object之间的区别小心(这实在是低技术含量和未施加)和managed_shared_memory/managed_mapped_file(两者使用segment_manager)。

您正在使用后者。


“假设它是可以接受的读者不要地图的大小的变化的更新”:

我不认为这个假设是如何成立。

管理的段本质上构成了辅助内​​存堆及其关联的控制结构。

控制结构包含诸如“堆”的实际范围等细节是有意义的。由于控制结构位于共享内存中,因此它们必须位于已经映射到读取进程中的部分。

更改内存段的大小会更改该控制结构中的值,该值可从映射相同共享内存的所有进程中看到。这显然会在实际上没有足够的内存映射以满足新扩展(导致页面错误,最好)的进程中造成严重破坏。

现在,I 可以想象一个非常智能的实现,它避免了对这种控制信息的需求(例如像一个带有标记值的经典空闲块列表)。但我不认为Boost Interprocess已经采用了这种路线¹,并且您引用的文字强烈暗示该设计不适合这种灵活性。

可以使用作者的managed_mapped_file :: grow,假设读者可以接受不更新地图大小的更改吗?

不,它不好。

我的假设是,读者的地图将保持有效,然后当我需要他们从作者处获取最新更改时,我可以用更新的大小重新映射读者。它是否正确?

毫无疑问,/ maps /会很好(取决于grow的实现方式,但我认为我已经通过实验证实了这一点)。问题在于顶部运行的segment_manager。这是一个会被混淆的人。

¹纯Fingerspitzengefühl