提升进程间共享内存删除对象而不破坏

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&lt;MyVector&gt;("Data") 时被调用,如果我调用 delete vec 应用程序崩溃。

现在如何在不破坏基础数据的情况下正确释放对象“vec”? 完整场景:

两个用户正在运行我的软件,通过共享内存共享数据(在使用文件模拟的 Windows 中) 一个用户退出软件,如果我不调用 destroy,我有内存泄漏,如果我按照 boost 文档中的说明调用它:

在 Windows 操作系统中,当前版本支持通常可接受的 UNIX 取消链接行为模拟:使用随机名称重命名文件并标记为在最后打开的句柄关闭时删除

另一个用户启动该软件并尝试共享内存,但由于文件已重命名,它无法与我的软件的其他运行实例共享内存。

【问题讨论】:

【参考方案1】:

向量是由创建或打开的

这有点混淆了概念。它已被查找,并在必要时构建。 (open_or_create 适用于实际的可共享对象,例如内存映射或共享内存对象)。

我检查了 vec 的 d'tor 仅在我使用 shm.destroy&lt;MyVector&gt;("Data") 时被调用,如果我调用 delete vec 应用程序崩溃。

这都是设计使然。

一个用户退出软件,如果我不调用 destroy 我有内存泄漏,

不是真的。如果不销毁向量,它仍然存在于托管段中。这意味着您可以重新打开共享内存段,仍然可以在那里找到它。

要删除共享段,请使用remove()

docs 说这与此有关:

当 managed_mapped_file 对象被销毁时,文件会自动解映射,所有资源都被释放。要从文件系统中删除文件,您可以使用标准 C std::remove 或 Boost.Filesystem 的 remove() 函数,但如果任何进程仍然在内存中映射文件或文件被任何进程打开,则文件删除可能会失败。

要获得更便携的行为,请使用 file_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

【讨论】:

以上是关于提升进程间共享内存删除对象而不破坏的主要内容,如果未能解决你的问题,请参考以下文章

boost中的异常:进程间,共享内存对象删除

linux 实现共享内存同步

Linux 进程间通信 共享内存

使用类内的类提升进程间共享内存

在没有共享内存的情况下提升进程间字符串

SystemV标准的Linux进程间通信共享内存