我的问题是在单个编写器进程和多个读取器进程的上下文中使用Boost.Interprocess增长内存映射区域。 是否可以使用作者的managed_mapped_file::grow
,假设读者可以接受不更新地图大小的更改?我的假设是读者的地图将保持有效,然后当我需要他们从作者那里获取最新的更改时,我可以用更新的大小重新映射读者。这是对的吗?
文档的Growing managed segments部分说:
创建托管细分受众群后,托管细分受众群无法成长。该限制不易解决:需要停止附加到托管段的每个进程,通知新大小,他们需要重新映射托管段并继续工作。 [...]
这让我觉得我可以grow
,只要我没有立即更新读者就可以了。但是,文档继续说:
另一方面,Boost.Interprocess提供离线细分市场增长。这是什么意思?如果没有进程映射托管段,则可以增长该段。如果应用程序可以找到没有附加进程的时刻,它可以增长或缩小以适应托管段。 [...]
managed_mapped_file
还提供类似的功能来增长或shrink_to_fit
托管文件。请记住,在执行增长/缩小过程时,不应该修改文件/共享内存。否则,托管分段将被破坏。
这让我觉得我不能做我想做的事,但我不明白为什么它不起作用。
答案 0 :(得分:1)
让我们仔细区分shared_memory_object
(实际上是低技术和非实力)和managed_shared_memory
/ managed_mapped_file
(都使用segment_manager
)。
你正在使用后者。
“假设读者可以接受不更新地图大小的更改”:
我不明白这个假设是如何实现的。
托管段本质上构成一个辅助内存堆及其相关的控制结构。
控制结构包含诸如“堆”的实际范围之类的细节是有意义的。由于控制结构位于共享内存中,因此它们必须位于已映射到读取过程的部分中。
更改内存段的大小将更改该控制结构中的值,该值从映射相同共享内存的所有进程中可见。这显然会在实际上没有足够的内存映射来满足新扩展区的进程中造成严重破坏(最多导致页面错误)。
现在,我可以想象一个非常智能的实现,它可以避免对这种控制信息的需求(例如,带有标记值的经典空闲块列表)。但我不希望Boost Interprocess采用这条路线¹,你引用的文字强烈暗示设计不能满足这种灵活性。
从编者那里使用managed_mapped_file :: grow是否可以,假设读者可以接受不更新地图大小的更改?
不,不行。
我的假设是读者的地图将保持有效,然后当我需要他们从作者那里获取最新的更改时,我可以用更新的大小重新映射读者。这是对的吗?
/ maps /会很好,毫无疑问(取决于grow
的实施方式,但我想我之前已通过实验证实过)。问题在于segment_manager
在顶部运行。这是一个令人困惑的问题。
¹纯Fingerspitzengefühl