Growing Boost.使用单个写入器的进程间内存映射文件
Growing Boost.Interprocess memory mapped file with single writer
我的问题是关于在单个写入器进程和多个读取器进程的上下文中使用Boost.Interprocess增加内存映射区域。是否可以使用作者的managed_mapped_file::grow
,假设读者不更新地图大小的变化是可以接受的?我的假设是读者的地图将保持有效,然后当我需要他们从作者那里获取最新更改时,我可以使用更新的大小重新映射读者。这是对的吗?
文档的"不断增长的托管细分"部分指出:
创建受管理的细分后,无法扩展受管理的细分。这个限制不容易解决:附加到托管段的每个进程都需要停止,通知新的大小,他们需要重新映射托管段并继续工作。[...]
这让我觉得我可以grow
,只要我对读者没有立即更新很好。但是,文档继续说:
另一方面,Boost.Interprocess提供离线细分市场的增长。这是什么意思?如果没有进程映射托管分段,则可以增长分段。如果应用程序可以找到未附加进程的时刻,则可以增大或缩小以适应托管段。[...]
managed_mapped_file
还提供了类似的功能来增大或shrink_to_fit
托管文件。请记住,在执行增长/收缩过程时,任何进程都不应修改文件/共享内存。否则,托管分段将损坏。
这让我觉得我不能做我想做的事情,但我不明白为什么它不起作用。
让我们仔细区分shared_memory_object
(这确实是低技术且不强加的)和managed_shared_memory
/managed_mapped_file
(两者都使用segment_manager
)。
您正在使用后者。
"假设读者可以接受不更新地图大小的变化":
我不明白这个假设如何成立。
受管段实质上构成一个辅助内存堆及其关联的控制结构。
控制结构包含详细信息(例如该"堆"的实际范围)是有意义的。由于控制结构位于共享内存中,因此它们也必须位于已映射到读取进程中的部分中。
更改内存段的大小将更改该控制结构中的值,该值从映射同一共享内存的所有进程中可见。这显然会对实际上没有足够的内存映射来满足新扩展数据块的进程造成严重破坏(充其量会导致页面错误)。
现在,我可以想象一个非常聪明的实现来规避对此类控制信息的需求(例如,具有哨兵值的经典自由阻止列表)。但我不认为 Boost Interprocess 会走这条路¹,你引用的文字强烈表明该设计不符合这种灵活性。
是否可以使用编写器的 managed_mapped_file::grow,假设读者可以接受不更新地图大小的变化?
不,这不行。
我的假设是读者的地图将保持有效,然后当我需要他们从作者那里获取最新更改时,我可以使用更新的大小重新映射读者。这是对的吗?
毫无疑问,/maps/会很好(取决于grow
的实现方式,但我想我之前已经通过实验证实了这一点)。问题出在上面运行的segment_manager
。这是要混淆的。
¹ 纯指尖
- 可以读入进程内存的最大块大小是多少?
- 如何读取特定地址的进程内存?
- 如何删除列出的"QGraphicsPathItem"对象以控制进程内存使用情况?
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 读取进程内存多级指针(DLL 注入)
- 读取进程内存作弊引擎值
- 获取进程内存信息失败,错误 6 句柄无效
- c++ 读取进程内存基址 + 偏移量不起作用
- 如何编辑受保护的进程内存?
- 内核模式驱动程序可以在任何进程上执行读取进程内存吗?
- 如何获取进程内存的最小值和最大值?(C++)
- C++ - 读取进程内存到缓冲区,写入进程内存(同一缓冲区上的新值)将缓冲区恢复为旧值
- 读取进程内存 C++ 不会读取
- 尝试编写进程内存并获取用户定义的文字运算符未找到
- 具有多个偏移量的写入进程内存C++
- C++如何使用读取进程内存查找进程内存中使用的最后一个(偏移量 - 地址)
- 读取进程内存无法正常工作,使用 UTF16 字符串
- 读取进程内存上的错误 299
- 写入进程内存没有错误,它不会写入正确的地址
- 将进程内存转储到文件/从转储文件重新创建进程