提升进程间共享内存删除对象而不破坏
Posted
技术标签:
【中文标题】提升进程间共享内存删除对象而不破坏【英文标题】:Boost interprocess shared memory delete object without destroy 【发布时间】:2017-05-05 10:15:20 【问题描述】:我在 Windows 上有一个 boost 进程间 managed_shared_memory,我有一个 boost 进程间向量存储在其中。向量由以下人创建或打开
auto* vec = shm.find_or_construct< MyVector >( "Data" )( shmAllocator );
如 boost 进程间示例中所述。我的意思是我现在构造或打开了一个对象vec
引用共享内存中的对象。我检查了 vec 的 d'tor 仅在我使用 shm.destroy<MyVector>("Data")
时被调用,如果我调用 delete vec
应用程序崩溃。
现在如何在不破坏基础数据的情况下正确释放对象“vec”? 完整场景:
两个用户正在运行我的软件,通过共享内存共享数据(在使用文件模拟的 Windows 中) 一个用户退出软件,如果我不调用destroy
,我有内存泄漏,如果我按照 boost 文档中的说明调用它:
另一个用户启动该软件并尝试共享内存,但由于文件已重命名,它无法与我的软件的其他运行实例共享内存。在 Windows 操作系统中,当前版本支持通常可接受的 UNIX 取消链接行为模拟:使用随机名称重命名文件并标记为在最后打开的句柄关闭时删除
【问题讨论】:
【参考方案1】:向量是由创建或打开的
这有点混淆了概念。它已被查找,并在必要时构建。 (open_or_create
适用于实际的可共享对象,例如内存映射或共享内存对象)。
我检查了 vec 的 d'tor 仅在我使用
shm.destroy<MyVector>("Data")
时被调用,如果我调用delete vec
应用程序崩溃。
这都是设计使然。
一个用户退出软件,如果我不调用 destroy 我有内存泄漏,
不是真的。如果不销毁向量,它仍然存在于托管段中。这意味着您可以重新打开共享内存段,仍然可以在那里找到它。
要删除共享段,请使用remove()
docs 说这与此有关:
当 managed_mapped_file 对象被销毁时,文件会自动解映射,所有资源都被释放。要从文件系统中删除文件,您可以使用标准 C
std::remove
或 Boost.Filesystem 的remove()
函数,但如果任何进程仍然在内存中映射文件或文件被任何进程打开,则文件删除可能会失败。要获得更便携的行为,请使用 f
ile_mapping::remove(const char *)
操作,即使文件正在被映射,它也会删除文件。但是,如果文件(例如通过 C++ 文件流)并且没有授予文件删除共享权限,则在某些操作系统系统中删除将失败。但在最常见的情况下,file_mapping::remove
足够便携。
还有here:
~basic_managed_mapped_file();
销毁
*this
并指示调用进程已使用资源完成。析构函数将释放系统分配的任何系统资源,供该进程用于该资源。资源仍然可以再次调用 open 构造函数重载打开。要从系统中删除资源,请使用remove()
其他信息
如果您真的只是希望向量在最后一个用户释放它之后消失,请使用进程间 shared_pointer:http://www.boost.org/doc/libs/1_64_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.shared_ptr
【讨论】:
以上是关于提升进程间共享内存删除对象而不破坏的主要内容,如果未能解决你的问题,请参考以下文章